为什么不试试手写bitset呢QAQ
存在字符x
对应二进制第x-'A'
位为1
这样就是线段树维护区间或了
#include"cstdio"
#include"cstring"
#include"iostream"
#include"algorithm"
using namespace std;
const int MAXN=1<<19;
const int siz=3;
int n,m;
char ch[MAXN];
int tag[MAXN<<1],tree[MAXN<<1];
void build(int k,int l,int r)
{
tag[k]=-1;
if(l==r){
tree[k]=1<<(ch[l]-'A');
return;
}int i=k<<1,mid=l+r>>1;
build(i,l,mid);build(i|1,mid+1,r);
tree[k]=tree[i]|tree[i|1];
return;
}
void po(int k,int l,int r)
{
if(l==r||tag[k]==-1) return;
int i=k<<1;
tree[i]=tree[i|1]=1<<tag[k];
tag[i]=tag[i|1]=tag[k];
tag[k]=-1;
return;
}
void cchg(int k,int l,int r,int le,int ri,int x)
{
po(k,l,r);
if(le<=l&&r<=ri){
tree[k]=1<<x;
tag[k]=x;
return;
}int i=k<<1,mid=l+r>>1;
if(le<=mid) cchg(i,l,mid,le,ri,x);
if(mid<ri) cchg(i|1,mid+1,r,le,ri,x);
tree[k]=tree[i]|tree[i|1];
return;
}
int cask(int k,int l,int r,int le,int ri)
{
po(k,l,r);
if(le<=l&&r<=ri) return tree[k];
int ans=0;
int i=k<<1,mid=l+r>>1;
if(le<=mid) ans|=cask(i,l,mid,le,ri);
if(mid<ri) ans|=cask(i|1,mid+1,r,le,ri);
return ans;
}
int count(int x)
{
int sum=0;
while(x) ++sum,x&=x-1;
return sum;
}
int main()
{
scanf("%d",&n);
scanf("%s",ch+1);
build(1,1,n);
scanf("%d",&m);
while(m--){
char p,c;int l,r;
scanf("
%c%d%d",&p,&l,&r);
if(p=='A'){
scanf("
%c",&c);
cchg(1,1,n,l,r,(int)c-'A');
}else{
if(l==1||r==n){
int ct=cask(1,1,n,l,r);
if(count(ct)==1) puts("Yes");
else puts("No");
}else{
int ct=cask(1,1,n,l,r),tp1=cask(1,1,n,l-1,l-1),tp2=tp1|cask(1,1,n,r+1,r+1);
if(count(ct)==1&&count(tp2)==2) puts("Yes");
else puts("No");
}
}
}return 0;
}