码迷,mamicode.com
首页 > 其他好文 > 详细

【luogu2787】 语文1(chin1)- 理理思维 [线段树]

时间:2019-10-23 20:07:25      阅读:82      评论:0      收藏:0      [点我收藏+]

标签:return   lin   operator   node   void   pen   图片   区分大小写   www   

P2787 语文1(chin1)- 理理思维

P2787 语文1(chin1)- 理理思维

实名哭泣QAQ 我把tg搞错了 调了一下午

因为是将字母对应为\(0\sim 25\)所以无tg不能为\(0\)应为\(-1\) 我TM因为这个调了一下午!!!!!!!!!!!!

技术图片

啊啊啊啊啊啊啊啊啊啊啊啊啊啊

注意本题不区分大小写

排序就将其拆成一个一个的单个区间修改

int chan(char x){return ('a'<=x&&x<='z')?x-'a':x-'A';}
struct node{
    int cnt[26],tg;
    node(){memset(cnt,0,sizeof(cnt));tg=-1;}
}t[N<<2];
node operator + (node x,node y){
    node z;
    for(int i=0;i<26;++i) z.cnt[i]=x.cnt[i]+y.cnt[i];
    return z;
}
void pup(int o){t[o]=t[ls]+t[rs];}
void updnode(int o,int l,int r,int k){
    memset(t[o].cnt,0,sizeof(t[o].cnt));
    t[o].tg=k,t[o].cnt[k]=r-l+1;
}
void pudw(int o,int l,int r){
    if(t[o].tg==-1) return;
    int mid=l+r>>1;
    updnode(ls,l,mid,t[o].tg),updnode(rs,mid+1,r,t[o].tg),t[o].tg=-1;
}
void mdf(int o,int l,int r,int x,int y,int k){
    if(l>y||r<x) return;
    if(x<=l&&r<=y) return updnode(o,l,r,k);
    pudw(o,l,r);int mid=l+r>>1;
    mdf(ls,l,mid,x,y,k),mdf(rs,mid+1,r,x,y,k);
    pup(o);
}
node query(int o,int l,int r,int x,int y){
    if(x<=l&&r<=y) return t[o];
    int mid=l+r>>1;pudw(o,l,r);
    node ret;
    memset(ret.cnt,0,sizeof(ret.cnt));
    if(x<=mid) ret=ret+query(ls,l,mid,x,y);
    if(y>mid) ret=ret+query(rs,mid+1,r,x,y);
    return pup(o),ret;
}
void build(int o,int l,int r){
    if(l==r){t[o].cnt[chan(a[l])]=1;return;}
    int mid=l+r>>1;
    build(ls,l,mid),build(rs,mid+1,r);
    pup(o);
}

int main(){
#ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin);
#endif
    rd(n),rd(m),scanf("%s",a+1);
    build(1,1,n);char k;
    for(int i=1,opt,x,y;i<=m;++i){
        rd(opt),rd(x),rd(y);
        if(opt!=3) cin>>k;
        if(opt==1) 
        printf("%d\n",query(1,1,n,x,y).cnt[chan(k)]);
        else if(opt==2) mdf(1,1,n,x,y,chan(k));
        else if(opt==3){
            node ret=query(1,1,n,x,y);
            for(int i=0,r;i<26;++i){if(!ret.cnt[i]) continue;r=x+ret.cnt[i]-1;mdf(1,1,n,x,r,i),x=r+1;           }
        }
/*      for(int i=0;i<26;++i) printf("%d ",t[1].cnt[i]);
        puts("");*/
    }
    return 0;

技术图片

【luogu2787】 语文1(chin1)- 理理思维 [线段树]

标签:return   lin   operator   node   void   pen   图片   区分大小写   www   

原文地址:https://www.cnblogs.com/lxyyyy/p/11728304.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!