题解:P4979
题面
![[../../题面/洛谷题面/P4979|P4979]]
分析
裸区间推平,裸区间判同,珂朵莉树和线段树+lazytag均可。
线段树细节较多,谨慎处理
珂朵莉需在判同的时候,顺便进行合并,否则被 hack
代码
线段树
珂朵莉
#include <bits/stdc++.h>
#define IT set<node>::iterator
using namespace std;
const int N=1e6+1;
inline int read(){
int x=0,w=1;
char ch=getchar();
while(ch<'0'||ch>'9')(ch=='-')&&(w=-1,0),ch=getchar();
while(ch>='0'&&ch<='9')x=(x*10)+(ch^48),ch=getchar();
return x*w;
}
inline void wrt(int x){
if(x<0)putchar('-'),x=-x;
if(x>9)wrt(x/10);
putchar(x%10^48);
}
inline char getc(){
char ch=getchar();
while(ch!='A'&&ch!='B'&&ch!='C')ch=getchar();
return ch;
}
struct node{
int l,r;
mutable char v;
bool operator<(const node& o)const{return l<o.l;}
};
set<node>odt;
int n,m,l,r,cnt=1;
char str[N],lst,op;
IT itl,itr,tmp,it;
IT split(int pos){
if(pos>n)return odt.end();
it=odt.lower_bound({pos,0,0});
if(it!=odt.end()&&it->l==pos)return it;
--it;
if(it->r<pos)return odt.end();
int L=it->l,R =it->r;
char V=it->v;
odt.erase(it);
odt.insert({L,pos-1,V});
return odt.insert({pos,R,V}).first;
}
void assign(int l,int r,char v){
itr=split(r+1),itl=split(l);
odt.erase(itl,itr);
odt.insert(node{l,r,v});
}
char ask(int pos){return split(pos)->v;}
bool check(int l,int r){
itr=split(r+1),itl=split(l);
tmp=itl;
for(;itl!=itr;++itl)if(itl->v!=tmp->v)return 0;
return 1;
}
int main(){
n=read(),scanf("%s",str+1),lst=str[1];
for(int i=1;i<=n;++i){
if(str[i]==lst)++cnt;
else odt.insert(node{i-cnt,i-1,lst}),lst=str[i],cnt=1;
}
odt.insert(node{n+1-cnt,n,lst});
m=read();
while(m--){
op=getc(),l=read(),r=read();
if(op=='A')assign(l,r,getc());
else{
if(!check(l,r))puts("No");
else{
if(l==1||r==n||ask(r+1)!=ask(l-1))puts("Yes");
else puts("No");
}
assign(tmp->l,(--itl)->r,tmp->v);//for hack
}
}
return 0;
}

浙公网安备 33010602011771号