问题描述

LG4979


题解

珂朵莉树+O2简直就是绝配

对于操作 A ,直接 \(\mathrm{assign}\) 推平就完事了。

对于操作 B ,如果它左右端点有在边界上的,直接把区间 \([l,r]\)撕出来判断就完了,如果不在边界上,先把单点 \({l-1,r+1}\) 撕出来判,如果符合条件,再撕 \([l,r]\) 出来判。


\(\mathrm{Code}\)

#include<bits/stdc++.h>
using namespace std;

#define IT set<node>::iterator

template <typename Tp>
void read(Tp &x){
    x=0;char ch=1;int fh;
    while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
    if(ch=='-'){fh=-1;ch=getchar(); }
    else fh=1;
    while(ch>='0'&&ch<='9') x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
    x*=fh;
}

const int maxn=500007;

struct node{
    int l,r;
    mutable char v;
    node(int L,int R=-1,char V=0):l(L),r(L),v(V){}
    bool operator <(node a)const{
        return l<a.l;
    }
};

char a[maxn];
set<node>s;

IT split(int pos){
    IT it=s.lower_bound(node(pos));
    if(it!=s.end()&&it->l==pos) return it;
    --it;
    int L=it->l,R=it->r;char V=it->v;
    s.erase(it);s.insert(node(L,pos-1,V));
    return s.insert(node(pos,R,V)).first;
}

void assign(int l,int r,char val){
    IT rr=split(r+1),ll=split(l);
    s.erase(ll,rr);s.insert(node(l,r,val));
}

char gec(int pos){
    IT it=split(pos);
    return it->v;
}

bool check(int l,int r){
    IT rr=split(r+1),ll=split(l);
    char k=ll->v;
    for(;ll!=rr;++ll) if(ll->v!=k) return false;
    return true;
}

int T,x,y,z,n;
char c;
int main(){
    read(n);scanf("%s",a+1);
    int cnt=1;char las=a[1];
    for(int i=2;i<=n;i++){
        if(a[i]==las) ++cnt;
        else{
            s.insert(node(i-cnt,i-1,las));las=a[i],cnt=1;
        }
    }
    s.insert(node(n+1-cnt,n,las));
    read(T);
    while(T--){
        cin>>c;int op=c-'A'+1;
        if(op==1){char z;
            read(x);read(y);cin>>z;
            assign(x,y,z);
        }
        else{
            read(x);read(y);
            if(x==1||x==n||y==1||y==n){
                if(check(x,y)) puts("Yes");
                else puts("No");
            }
            else{
                int aa=gec(x-1),bb=gec(y+1);
                if(aa==bb||!check(x,y)) puts("No");
                else puts("Yes");
            }
        }
    }
    return 0;
}