[AT_abc419_d] Substr Swap 题解

题目大意

对于字符串 \(S\)\(T\)。有 \(M\) 个操作,每次操作给定 \(L_i\)\(R_i\),交换 \(S\)\(T\)\(L_i\)\(R_i\)。求执行完所有操作后的 \(S\)

1.暴力

按题意模拟即可。

时间复杂度:\(O(NM)\),显然超时。

2.正解

不难发现,假设 \(S\) 的一个字符被交换了奇数次,那么它最终会到 \(T\) 中,被交换偶数次最终依然在 \(S\) 中,所以我们用数组 \(d\) 记录 \(S_i\) 被交换了几次。对于每次操作,我们让 \(d_L\)\(d_R\) 全部加一。

根据让 \(d_L\)\(d_R\) 全部加一不难想到差分操作,所以用差分维护 \(d\) 数组。执行完所有操作后,如果 \(d_i\) 是奇数就输出 \(T_i\),否则输出 \(S_i\)

时间复杂度:\(O(N+M)\),可以 AC。

AC code:

#include<bits/stdc++.h>
using namespace std;
int d[500005];
void add(int l,int r){//d[l]到d[r]全部+1
	d[l]++;
	d[r+1]--;
}
int main(){
	ios::sync_with_stdio(0);
	cin.tie(0),cout.tie(0);
	int n,m;
	string a,b;
	cin>>n>>m>>a>>b;
	while(m--){
		int l,r;
		cin>>l>>r;
		l--,r--;//注意这里,因为字符串从0开始所以l和r要-1
		add(l,r);
	}
	for(int i=0;i<n;i++){
		d[i]+=d[i-1];//先还原
		if(d[i]&1) cout<<b[i];
		else cout<<a[i];
	}
    return 0;
}
posted @ 2025-08-19 20:35  Frums  阅读(21)  评论(0)    收藏  举报