专栏文章
题解:P12921 [POI 2021/2022 R3] 挑剔的 Bajtazar / Wybredny Bajtazar
P12921题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @mint0sjb
- 此快照首次捕获于
- 2025/12/02 07:52 3 个月前
- 此快照最后确认于
- 2025/12/02 07:52 3 个月前
只有五个字符,我们直接上线段树维护。
使用线段树二分找到修改的区间。对于将区间内所有的 变为 的操作,我们设转化函数 作为延迟更新标记, 则 ,否则 ,可以发现标记的更新实质上是函数的复合。所以直接维护函数的复合即可。
线段树记录每个结点所维护区间的各字符数量,每个结点的标记,其余线段树标准套路维护即可。
CPP#include<iostream>
#include<algorithm>
const int sz=1e6+10;
std::string s;
struct SegT{
int sum[sz<<2][5],tag[sz<<2][5];
void build(int p,int ln,int rn){
for(int x:{0,1,2,3,4})tag[p][x]=x;
if(ln==rn)return sum[p][s[ln]-'a']=1,void();
int mid=ln+rn>>1;
build(p<<1,ln,mid);
build(p<<1|1,mid+1,rn);
for(int x:{0,1,2,3,4})sum[p][x]=sum[p<<1][x]+sum[p<<1|1][x];
}
void push(int p,int trs[5]){
static std::basic_string<int>S(5,0),T(5,0);
S.assign(5,0),T.assign(5,0);
for(int x:{0,1,2,3,4})S[trs[x]]+=sum[p][x],T[x]=trs[tag[p][x]];
for(int x:{0,1,2,3,4})sum[p][x]=S[x],tag[p][x]=T[x];
}
void pushdown(int p,int ln,int rn){
push(p<<1,tag[p]),push(p<<1|1,tag[p]);
for(int x:{0,1,2,3,4})tag[p][x]=x;
}
void change(int p,int ln,int rn,int l,int r,int trs[5]){
if(ln>=l&&rn<=r)return push(p,trs);
int mid=ln+rn>>1;
pushdown(p,ln,rn);
if(l<=mid)change(p<<1,ln,mid,l,r,trs);
if(r>mid)change(p<<1|1,mid+1,rn,l,r,trs);
for(int x:{0,1,2,3,4})sum[p][x]=sum[p<<1][x]+sum[p<<1|1][x];
}
int find(int p,int ln,int rn,int x,int k){
if(ln==rn)return ln;
int mid=ln+rn>>1;
pushdown(p,ln,rn);
if(sum[p<<1][x]>=k)return find(p<<1,ln,mid,x,k);
else return find(p<<1|1,mid+1,rn,x,k-sum[p<<1][x]);
}
void print(int p,int ln,int rn){
if(ln==rn){
for(int x:{0,1,2,3,4})
if(sum[p][x]!=0)std::cout<<(char)(x+'a');
return;
}
int mid=ln+rn>>1;
pushdown(p,ln,rn);
print(p<<1,ln,mid);
print(p<<1|1,mid+1,rn);
}
}st;
int main(){
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
int n,q;
std::cin>>n>>q>>s,s=" "+s;
st.build(1,1,n);
while(q--){
int p;
char a,b;
std::cin>>p>>a>>b;
int T[]={0,1,2,3,4};
T[a-'a']=b-'a';
int pos=st.find(1,1,n,a-'a',p);
st.change(1,1,n,1,pos,T);
}
st.print(1,1,n);
std::cout<<"\n";
return 0;
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...