1 条题解

  • 0
    @ 2026-5-4 21:08:32

    Solution

    显然,相同的字符可以缩成一个,因此不妨设两个字符都是 ab\texttt {ab} 交错的。

    考虑一次交换,对两个串产生的影响。我们最后要把串消成 a\texttt ab\texttt b,因此我们可以考虑用 S=len1+len2S=len_1+len_2 来衡量我们操作的优劣。

    1. 如果两个前缀末尾字符相同,那么这样做相当于平衡两个串的长度,而 SS 不变
    2. 如果两个前缀末尾字符不同,看起来会分别合并一个字符,即 SS 减少 22但是,如果两个前缀都是全串,那么相当于啥都没做;如果有一个串是前缀,那么 SS 只能减少 11

    因此,我们认为答案下界为 S22\lceil \dfrac{S-2}{2} \rceil,但它是否是答案下确界呢?

    分析一下:

    CASE I

    如果两个串的开头相同,形如 abab\texttt {abab}\cdotsabab\texttt{abab} \cdots,交换长度分别为 1122 的前缀,能让第一个串的长度 2-2,另一个不变。因此,我们每次对较长串进行操作。

    注意到这样做对两个长度都是 22 的串或者一个长度为 11 的串是行不通的。

    对于前者,情况已经确定,容易发现需要 22 此次操作;对于后者,另一个串的长度可能不确定。但是有一点可以确定:必然有一步只能让 SS 减少 11,因此可以把答案下界提升为 S12\lceil \dfrac{S-1}{2} \rceil

    如果两个串的长度都 2\ge 2,我们必定能用类似操作将字符串的长度最终变为 (2,2)(2,2)(1,3)(1,3)(1,2)(1,2) 中的一种(每次消去两个字符)。这三种情况可以证明都能用 S12\lceil \dfrac{S-1}{2} \rceil 步完成,也就是说下界能取到。

    如果有一个串的长度为 11,形如 a\texttt aababa\texttt {ababa} \cdots。下一步操作最多删掉一个字符。如果之后每一步都删去两个字符,那么答案是 S12\lceil \dfrac{S-1}{2} \rceil,否则要改为 S2\lceil \dfrac{S}{2} \rceil。容易发现,只有在 SS 是奇数的时候才关键,否则这两个式子值相等。分析可知,必须 S3(mod4)S \equiv 3 \pmod 4 才能让前者取到。

    很容易理解,我们上面这么做是最优的。

    更加本质的原因是,S=4S=4S=3S=3 时,都只能做出消掉一个字符的操作。

    CASE II

    如果两个串开头不同,形如 abab\texttt{abab} \cdotsbaba\texttt{baba} \cdots

    显然,我们可以化归为 CASE I,而且同时让长度减少 11。因此我们给出了 S2\lceil \dfrac{S}{2} \rceil 的构造。

    如果要更小,则一定就是 S22\lceil \dfrac{S-2}{2} \rceil 的了。若 SS 是偶数,显然这就要求每次都删掉两个数了;否则,可以有一次之删掉一个字符。

    一对串如果每次都能删掉两个字符,必定长度相等,首字母相反。

    SS 是偶数时,如果有一个串长度为 11,肯定做不到这一点(因为第一步删不掉两个元素)

    考虑每次交换长度为 mmnn 的前缀,则 2mn2 \mid m-n。这样两串长度差模 44 意义下是不变的

    因此 SS 是偶数的时候能取到 S22\lceil \dfrac{S-2}{2} \rceil 的充要条件是,两串长度在模 44 意义下相同。

    SS 为奇数时,可以通过交换两个简单的前缀,做到两个串的长度之差的绝对值 1\le 1,即做到了 S12\lceil \dfrac{S-1}{2} \rceil(但是有一个串长度为 11 的时候,两串长度差模 4433 的时候也不行……总之就是很多情况)


    解法中有一点小的 CORNER CASE。

    在 CASE I 中,其实当有一个串长度为 11 时,我们不能保证取到 S12\lceil \dfrac{S-1}{2} \rceil 的。

    所以到 CASE II 的讨论中,我们化归(交换较短串长度为 00 和较长串长度为 22 的前缀,这样会导致较短串长度加 11,较长串长度减 22)的时候,对于较长串长度 3\le 3 的情况会出现小问题。不过这些可以暴力讨论。

    代码写成了一大坨,非常难看。

    #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
    上传者