1 条题解
-
0
Solution
显然,相同的字符可以缩成一个,因此不妨设两个字符都是 交错的。
考虑一次交换,对两个串产生的影响。我们最后要把串消成 和 ,因此我们可以考虑用 来衡量我们操作的优劣。
- 如果两个前缀末尾字符相同,那么这样做相当于平衡两个串的长度,而 不变。
- 如果两个前缀末尾字符不同,看起来会分别合并一个字符,即 减少 。但是,如果两个前缀都是全串,那么相当于啥都没做;如果有一个串是前缀,那么 只能减少 。
因此,我们认为答案下界为 ,但它是否是答案下确界呢?
分析一下:
CASE I
如果两个串的开头相同,形如 和 ,交换长度分别为 和 的前缀,能让第一个串的长度 ,另一个不变。因此,我们每次对较长串进行操作。
注意到这样做对两个长度都是 的串或者一个长度为 的串是行不通的。
对于前者,情况已经确定,容易发现需要 此次操作;对于后者,另一个串的长度可能不确定。但是有一点可以确定:必然有一步只能让 减少 ,因此可以把答案下界提升为 。
如果两个串的长度都 ,我们必定能用类似操作将字符串的长度最终变为 、、 中的一种(每次消去两个字符)。这三种情况可以证明都能用 步完成,也就是说下界能取到。
如果有一个串的长度为 ,形如 和 。下一步操作最多删掉一个字符。如果之后每一步都删去两个字符,那么答案是 ,否则要改为 。容易发现,只有在 是奇数的时候才关键,否则这两个式子值相等。分析可知,必须 才能让前者取到。
很容易理解,我们上面这么做是最优的。
更加本质的原因是, 和 时,都只能做出消掉一个字符的操作。
CASE II
如果两个串开头不同,形如 和 。
显然,我们可以化归为 CASE I,而且同时让长度减少 。因此我们给出了 的构造。
如果要更小,则一定就是 的了。若 是偶数,显然这就要求每次都删掉两个数了;否则,可以有一次之删掉一个字符。
一对串如果每次都能删掉两个字符,必定长度相等,首字母相反。
当 是偶数时,如果有一个串长度为 ,肯定做不到这一点(因为第一步删不掉两个元素)
考虑每次交换长度为 和 的前缀,则 。这样两串长度差模 意义下是不变的。
因此 是偶数的时候能取到 的充要条件是,两串长度在模 意义下相同。
当 为奇数时,可以通过交换两个简单的前缀,做到两个串的长度之差的绝对值 ,即做到了 (但是有一个串长度为 的时候,两串长度差模 余 的时候也不行……总之就是很多情况)
解法中有一点小的 CORNER CASE。
在 CASE I 中,其实当有一个串长度为 时,我们不能保证取到 的。
所以到 CASE II 的讨论中,我们化归(交换较短串长度为 和较长串长度为 的前缀,这样会导致较短串长度加 ,较长串长度减 )的时候,对于较长串长度 的情况会出现小问题。不过这些可以暴力讨论。
代码写成了一大坨,非常难看。
#include<bits/stdc++.h> #define ffor(i,a,b) for(int i=(a);i<=(b);i++) #define roff(i,a,b) for(int i=(a);i>=(b);i--) using namespace std; const int MAXN=2e5+10; int n,m,sc,tc; vector<pair<int,int>> ans; string S,T; stack<int> s,t; void solve(int sc,int tc) { if(sc==1&&tc==1) return ; if(sc==1&&tc==2) return ans.push_back({0,t.top()}),void(); if(sc==2&&tc==1) return ans.push_back({s.top(),0}),void(); if(sc==2&&tc==2) { int a1=s.top(),a2=t.top(); s.pop(),t.pop(); int b1=s.top(),b2=t.top(); return ans.push_back({a1,0}),ans.push_back({b1,a1+a2}),void(); } if(sc==1&&tc==3) { int a1=s.top(),a2=t.top(),b,a3; t.pop(),b=t.top(),t.pop(),a3=t.top(); ans.push_back({0,a2}),ans.push_back({a1+a2,b}); return ; } if(sc==3&&tc==1) { int a1=t.top(),a2=s.top(),b,a3; s.pop(),b=s.top(),s.pop(),a3=s.top(); ans.push_back({a2,0}),ans.push_back({b,a1+a2}); return ; } if(sc==1) { if(tc%4==2) { vector<int> ttt; int tot=0; ffor(i,1,tc/2) ttt.push_back(t.top()),tot+=t.top(),t.pop(); ans.push_back({0,tot}); ttt[ttt.size()-1]+=s.top(),s.pop(); reverse(ttt.begin(),ttt.end()); for(auto id:ttt) s.push(id); ffor(i,1,tc/2-1) { int a1=s.top(),b1=t.top(); s.pop(),t.pop(); int b2=s.top(),a2=t.top(); s.pop(),t.pop(); ans.push_back({a1,b1}); s.push(b1+b2),t.push(a1+a2); } return ; } int a1=s.top(); s.pop(); int a2=t.top(); t.pop(); int b2=t.top(); t.pop(); ans.push_back({a1,a2+b2}); int a3=t.top(); t.pop(); t.push(a1+a3); s.push(b2),s.push(a2); sc=2,tc-=2; solve(sc,tc); return ; } if(tc==1) { if(sc%4==2) { vector<int> ttt; int tot=0; ffor(i,1,sc/2) ttt.push_back(s.top()),tot+=s.top(),s.pop(); ans.push_back({tot,0}); ttt[ttt.size()-1]+=t.top(),t.pop(); reverse(ttt.begin(),ttt.end()); for(auto id:ttt) t.push(id); ffor(i,1,sc/2-1) { int a1=s.top(),b1=t.top(); s.pop(),t.pop(); int b2=s.top(),a2=t.top(); s.pop(),t.pop(); ans.push_back({a1,b1}); s.push(b1+b2),t.push(a1+a2); } return ; } int a1=t.top(); t.pop(); int a2=s.top(); s.pop(); int b2=s.top(); s.pop(); ans.push_back({a2+b2,a1}); int a3=s.top(); s.pop(); s.push(a1+a3); t.push(b2),t.push(a2); tc=2,sc-=2; solve(sc,tc); return ; } if(sc<=tc) { int a1=s.top(); s.pop(); int b1=s.top(); s.pop(); int a2=t.top(); t.pop(); int b2=t.top(); t.pop(); int a3=t.top(); t.pop(); ans.push_back({a1,a2+b2}); s.push(b1+b2),s.push(a2); t.push(a1+a3); solve(sc,tc-2); return ; } else { int a1=t.top(); t.pop(); int b1=t.top(); t.pop(); int a2=s.top(); s.pop(); int b2=s.top(); s.pop(); int a3=s.top(); s.pop(); ans.push_back({a2+b2,a1}); t.push(b1+b2),t.push(a2); s.push(a1+a3); solve(sc-2,tc); return ; } } int main() { ios::sync_with_stdio(false),cin.tie(0),cout.tie(0); cin>>S>>T,n=S.size(),m=T.size(),S="&"+S,T="&"+T; int len=1; roff(i,n-1,1) if(S[i]==S[i+1]) len++; else s.push(len),len=1,sc++; s.push(len),len=1,sc++; roff(i,m-1,1) if(T[i]==T[i+1]) len++; else t.push(len),len=1,tc++; t.push(len),len=1,tc++; if(S[1]==T[1]) { solve(sc,tc); cout<<ans.size()<<'\n'; for(auto pr:ans) cout<<pr.first<<' '<<pr.second<<'\n'; return 0; } if(sc==tc&&sc==1) return cout<<0,0; if(sc==1&&tc==2) { int a=s.top(),b=t.top(); cout<<1<<'\n'<<a<<' '<<b; return 0; } if(sc==2&&tc==1) { int b=s.top(),a=t.top(); cout<<1<<'\n'<<b<<' '<<a; return 0; } if(sc==1&&tc==3) { int a1=s.top(); int b1=t.top(); t.pop(); int a2=t.top(); t.pop(); int b2=t.top(); t.pop(); cout<<2<<'\n'<<a1<<' '<<b1<<'\n'<<b1<<' '<<a1+a2; return 0; } if(sc==3&&tc==1) { int a1=t.top(); int b1=s.top(); s.pop(); int a2=s.top(); s.pop(); int b2=s.top(); s.pop(); cout<<2<<'\n'<<b1<<' '<<a1<<'\n'<<a1+a2<<' '<<b1; return 0; } if(sc==2&&tc==3) { int a1=s.top(),b1=t.top(); s.pop(),t.pop(); int b2=s.top(),a2=t.top(); s.pop(),t.pop(); int b3=t.top(); cout<<2<<'\n'<<a1<<' '<<b1<<'\n'<<b1+b2<<' '<<a1+a2<<'\n'; return 0; } if(sc==3&&tc==2) { int a1=t.top(),b1=s.top(); t.pop(),s.pop(); int b2=t.top(),a2=s.top(); t.pop(),s.pop(); int b3=s.top(); cout<<2<<'\n'<<b1<<' '<<a1<<'\n'<<a1+a2<<' '<<b1+b2<<'\n'; return 0; } if((sc+tc)%2==1) { int hf=(sc+tc-1)/2; if((max(sc,tc)-min(sc,tc))%4==1) { vector<int> ss,tt; if(sc<=tc) { int c1=0,c2=0; ffor(i,1,sc) c1+=s.top(),ss.push_back(s.top()),s.pop(); ffor(i,1,hf) c2+=t.top(),tt.push_back(t.top()),t.pop(); ss[ss.size()-1]+=t.top(),t.pop(); swap(ss,tt); ans.push_back({c1,c2}); } else { int c1=0,c2=0; ffor(i,1,tc) c2+=t.top(),tt.push_back(t.top()),t.pop(); ffor(i,1,hf) c1+=s.top(),ss.push_back(s.top()),s.pop(); tt[tt.size()-1]+=s.top(),s.pop(); swap(ss,tt); ans.push_back({c1,c2}); } reverse(ss.begin(),ss.end()); reverse(tt.begin(),tt.end()); for(auto id:ss) s.push(id); for(auto id:tt) t.push(id); sc=tc=hf; } else if(min(sc,tc)!=1) { vector<int> ss,tt; int dt=(max(sc,tc)-min(sc,tc)+1)/4; if(sc<=tc) { int c1=0,c2=0; ffor(i,1,1) c1+=s.top(),ss.push_back(s.top()),s.pop(),sc--; ffor(i,1,1+dt*2) c2+=t.top(),tt.push_back(t.top()),t.pop(),tc--; ss[ss.size()-1]+=t.top(),t.pop(),tc--; tt[tt.size()-1]+=s.top(),s.pop(),sc--; swap(ss,tt); ans.push_back({c1,c2}); } else { int c1=0,c2=0; ffor(i,1,1) c2+=t.top(),tt.push_back(t.top()),t.pop(),tc--; ffor(i,1,1+dt*2) c1+=s.top(),ss.push_back(s.top()),s.pop(),sc--; ss[ss.size()-1]+=t.top(),t.pop(),tc--; tt[tt.size()-1]+=s.top(),s.pop(),sc--; swap(ss,tt); ans.push_back({c1,c2}); } reverse(ss.begin(),ss.end()); reverse(tt.begin(),tt.end()); sc+=ss.size(),tc+=tt.size(); for(auto id:ss) s.push(id); for(auto id:tt) t.push(id); while(min(sc,tc)>1) { int a1=s.top(),b1=t.top(); s.pop(),t.pop(); int b2=s.top(),a2=t.top(); s.pop(),t.pop(); ans.push_back({a1,b1}); s.push(b1+b2),t.push(a1+a2); sc--,tc--; } ans.push_back({s.top(),t.top()}); cout<<ans.size()<<'\n'; for(auto pr:ans) cout<<pr.first<<' '<<pr.second<<'\n'; return 0; } } if(min(sc,tc)>=2&&(sc-tc)%4==0) { while(sc!=tc) { if(sc<tc) { sc++,tc-=3; int a1=s.top(); s.pop(); int b1=t.top(); t.pop(); int a2=t.top(); t.pop(); int b2=t.top(); t.pop(); int b3=s.top(); s.pop(); int a3=t.top(); t.pop(); ans.push_back({a1,b1+a2+b2}); s.push(b2+b3),s.push(a2),s.push(b1); t.push(a1+a3); } else { tc++,sc-=3; int a1=t.top(); t.pop(); int b1=s.top(); s.pop(); int a2=s.top(); s.pop(); int b2=s.top(); s.pop(); int b3=t.top(); t.pop(); int a3=s.top(); s.pop(); ans.push_back({b1+a2+b2,a1}); t.push(b2+b3),t.push(a2),t.push(b1); s.push(a1+a3); } } while(sc>1) { int a1=s.top(),b1=t.top(); s.pop(),t.pop(); int b2=s.top(),a2=t.top(); s.pop(),t.pop(); ans.push_back({a1,b1}); s.push(b1+b2),t.push(a1+a2); sc--; } cout<<ans.size()<<'\n'; for(auto pr:ans) cout<<pr.first<<' '<<pr.second<<'\n'; return 0; } if(max(sc,tc)>=4) { if(sc<=tc) { int a1=s.top(),b1=t.top(); s.pop(),t.pop(); int a2=t.top(); t.pop(); ans.push_back({0,b1+a2}); s.push(a1+a2),s.push(b1); sc++,tc-=2; solve(sc,tc); } else { int a1=t.top(),b1=s.top(); s.pop(),t.pop(); int a2=s.top(); s.pop(); ans.push_back({b1+a2,0}); t.push(a1+a2),t.push(b1); tc++,sc-=2; solve(sc,tc); } cout<<ans.size()<<'\n'; for(auto pr:ans) cout<<pr.first<<' '<<pr.second<<'\n'; return 0; } return 0; }过了 CF 上的完整数据。
- 1
信息
- ID
- 10763
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者