bzoj1493 线段树

来源:互联网 发布:优化推广什么意思 编辑:程序博客网 时间:2024/05/21 23:01

久违的写一发博客,真是调了好久。
显然F和R操作可以记录两个rev和mov值来忽略掉,剩下就是线段树基本操作了,主要是CS操作不懂它什么意思弄了好久- -

#include<cstdio>#include<algorithm>#include<cstring>#include<iostream>#define N 500005#define rep(i,a,b) for(int i=a;i<=b;i++)#define ll long longusing namespace std;int rev,mov,aa[N],n,Q,k,x,y,l,r,m;char s[10];struct Node{    int lval,rval,ans,lz;    Node *ls,*rs;    Node(){lz=0;}    void pushdown(int lf,int rg){        if(lz!=0){            int mid=(lf+rg)>>1;            ls->lz=rs->lz=lz;            ls->lval=ls->rval=rs->lval=rs->rval=lz;            ls->ans=1;            rs->ans=1;            lz=0;        }    }    void update(){        lval=ls->lval;        rval=rs->rval;        ans=ls->ans+rs->ans;        if(ls->rval==rs->lval)ans--;    }};Node pool[N*4],*tail=pool,*root;Node *build(int lf,int rg){    Node *nd=++tail;    if(lf==rg){        nd->lval=nd->rval=aa[lf];        nd->ans=1;    }    else{        int mid=(lf+rg)>>1;        nd->ls=build(lf,mid);        nd->rs=build(mid+1,rg);        nd->update();    }    return nd;}void modify(Node *nd,int lf,int rg,int L,int R,int val){    if(L<=lf&&rg<=R){        nd->ans=1;        nd->lval=nd->rval=val;        if(lf!=rg)        nd->lz=val;        return;    }    nd->pushdown(lf,rg);    int mid=(lf+rg)>>1;    if(L<=mid)        modify(nd->ls,lf,mid,L,R,val);    if(R>mid)        modify(nd->rs,mid+1,rg,L,R,val);    nd->update();}int get(int x){    int a=x;    if (rev) a=n-a+2;    a-=mov;    for (;a>n;a-=n);    for (;a<1;a+=n);    return a;}int query(Node *nd,int lf,int rg,int pos){    if(lf==rg)        return nd->lval;    int mid=(lf+rg)>>1;    nd->pushdown(lf,rg);    if(pos<=mid)        return query(nd->ls,lf,mid,pos);    else        return query(nd->rs,mid+1,rg,pos);}int query(Node *nd,int lf,int rg,int L,int R){    if(L<=lf&&rg<=R)        return nd->ans;    int mid=(lf+rg)>>1,ans=0,flag=-1;    nd->pushdown(lf,rg);    if(L<=mid)        ans+=query(nd->ls,lf,mid,L,R),flag=nd->ls->rval;    if(R>mid){        ans+=query(nd->rs,mid+1,rg,L,R);        if(flag==nd->rs->lval)ans--;    }    if(ans<=0)ans=1;    nd->update();    return ans;}int main(){    scanf("%d%d",&n,&m);    rep(i,1,n)    scanf("%d",&aa[i]);    root=build(1,n);    scanf("%d",&Q);    while(Q--){        scanf("%s",s);        if(s[0]=='R'){            scanf("%d",&k);            if(rev) mov-=k;else mov+=k;            for (;mov>n;mov-=n);            for (;mov<0;mov+=n);        }        if(s[0]=='F')            rev^=1;        if(s[0]=='S'){            scanf("%d%d",&x,&y);            l=get(x);r=get(y);            int v1=query(root,1,n,l),v2=query(root,1,n,r);            modify(root,1,n,l,l,v2);            modify(root,1,n,r,r,v1);        }        if(s[0]=='P'){            scanf("%d%d%d",&x,&y,&k);            l=get(x);r=get(y);            if(rev)swap(l,r);            if(l<=r)modify(root,1,n,l,r,k);            else{                modify(root,1,n,l,n,k);                modify(root,1,n,1,r,k);            }        }        if(s[0]=='C'&&s[1]!='S'){            int ans=root->ans;            if(root->lval==root->rval&&ans>1)ans--;            printf("%d\n",ans);        }        if(s[0]=='C'&&s[1]=='S'){            scanf("%d%d",&x,&y);            l=get(x);r=get(y);            if(rev)swap(l,r);            int ans;            if(l<=r){                ans=query(root,1,n,l,r);                if (l==1&&r==n&&ans>1&&root->lval==root->rval) ans--;            }            else{                ans=query(root,1,n,l,n)+query(root,1,n,1,r);                if (root->lval==root->rval) ans--;            }            printf("%d\n",ans);        }    }    return 0;   }
原创粉丝点击