解题思路:
一看到区间修改,直接开一个线段树维护每个区间字符的变化,用数组mp[26]记录,mp[i]=j表示字符i最终变成j。
#include<bits/stdc++.h> using namespace std; const int N=1e5+5; typedef long long ll; string s; class Node{ public: ll l,r; ll mp[26]; }tree[N<<2]; void build(int index,int l,int r) { tree[index].l=l;tree[index].r=r; for(int i=0;i<26;i++)tree[index].mp[i]=i;//初始化记录数组 if(l==r) { return; } int mid=(l+r)/2; build(index<<1,l,mid); build(index<<1|1,mid+1,r); } void push_down(int index)//向下传递记录 { for(int i=0;i<26;i++) { auto a=tree[index<<1].mp[i],b=tree[index<<1|1].mp[i]; tree[index<<1].mp[i]=tree[index].mp[a]; tree[index<<1|1].mp[i]=tree[index].mp[b]; } for(int i=0;i<26;i++)tree[index].mp[i]=i;//清除父节点的记录 } void update(int index,int l,int r,int x,int y)//区间修改 { if(tree[index].l>=l&&tree[index].r<=r) { for(int i=0;i<26;i++)if(tree[index].mp[i]==x)tree[index].mp[i]=y;//将最终态为x的变为y return; } push_down(index); if(tree[index<<1].r>=l)update(index<<1,l,r,x,y); if(tree[index<<1|1].l<=r)update(index<<1|1,l,r,x,y); } int query(int index,int k)//单点查询 { if(tree[index].l==tree[index].r) { int now=s[k]-'a'; now=tree[index].mp[now]; return now; } push_down(index); int ans=0; if(tree[index<<1].r>=k)ans+=query(index<<1,k); if(tree[index<<1|1].l<=k)ans+=query(index<<1|1,k); return ans; } int main( ) { cin>>s; s.insert(s.begin(),0); build(1,1,s.size()-1); int m;cin>>m; while(m--) { int l,r; char x,y; cin>>l>>r; getchar(); cin>>x; getchar(); cin>>y; update(1,l,r,x-'a',y-'a'); } for(int i=1;i<s.size();i++) { char ans='a'+query(1,i); cout<<ans; } return 0; }