[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;
}