zoukankan      html  css  js  c++  java
  • Bzoj1493--Noi2007项链工厂

    真™恶心,代码题就是痛苦

    我的想法是先双倍展开后线段树维护,双倍展开后Print和Swap的操作对于前后两边都要做一次,调了半天

    前两个操作可以不动线段树而把他询问的坐标转化到正确坐标即可

    代码 :

    #include<bits/stdc++.h>
    using namespace std;
    
    #define MAXN 500005
    
    int n,c,cl[MAXN*2];
    int q,Tf,Tv;
    char qe[4];
    
    inline int Tran(int x) {return Tf?((n-(x+Tv))%n+n)%n:(x+Tv)%n;}
    
    namespace SegmentTree{
        const int L=0,R=1;
        struct node{
            int son[2],be,nd,cs,set;
        }x[MAXN*4];
        int sz=1;
        
        inline void updata(int num) {
            x[num].be=x[x[num].son[L]].be;
            x[num].nd=x[x[num].son[R]].nd;
            x[num].cs=x[x[num].son[L]].cs+x[x[num].son[R]].cs;
            if(x[x[num].son[L]].nd==x[x[num].son[R]].be) x[num].cs--;
        }
        inline void Set(int num,int tc) {
            x[num].be=x[num].nd=x[num].set=tc;x[num].cs=1;
        }
        inline void maintain(int num) {
            Set(x[num].son[L],x[num].set);
            Set(x[num].son[R],x[num].set);
            x[num].set=0;
        }
        node Merge(node a,node b) {
            node ret;
            ret.be=a.be;ret.nd=b.nd;
            ret.cs=a.cs+b.cs;
            if(a.nd==b.be) ret.cs--;
            return ret;
        }
        
        void _init(int l,int r,int num) {
            if(l==r) {
                x[num].be=x[num].nd=cl[l];
                x[num].cs=1;return;
            }
            int mid=l+r>>1;
            x[num].son[L]=++sz;x[num].son[R]=++sz;
            _init(l,mid,x[num].son[L]);_init(mid+1,r,x[num].son[R]);
            updata(num);
        }
        
        void Print(int l,int r,int nl,int nr,int num,int tc) {
            if(l==nl&&r==nr) {Set(num,tc);return;}
            int mid=l+r>>1;
            if(x[num].set) maintain(num);
            if(nl>mid) Print(mid+1,r,nl,nr,x[num].son[R],tc);
            else if(nr<=mid) Print(l,mid,nl,nr,x[num].son[L],tc);
            else {
                Print(l,mid,nl,mid,x[num].son[L],tc);
                Print(mid+1,r,mid+1,nr,x[num].son[R],tc);
            }
            updata(num);
        }
        node TQurey(int l,int r,int nl,int nr,int num) {
            if(l==nl&&r==nr) return x[num];
            int mid=l+r>>1;node ret;
            if(nl>mid) ret=TQurey(mid+1,r,nl,nr,x[num].son[R]);
            else if(nr<=mid) ret=TQurey(l,mid,nl,nr,x[num].son[L]);
            else ret=Merge(TQurey(l,mid,nl,mid,x[num].son[L]),TQurey(mid+1,r,mid+1,nr,x[num].son[R]));
            if(x[num].set) {ret.be=ret.nd=x[num].set;ret.cs=1;}
            return ret;
        }
        int TColor(int p,int l,int r,int num) {
            if(l==r) return x[num].be;
            if(x[num].set) return x[num].set;
            int mid=l+r>>1;
            if(p>mid) return TColor(p,mid+1,r,x[num].son[R]);
            else return TColor(p,l,mid,x[num].son[L]);
        }
        
        inline int Qurey(int l,int r,bool cr) {
            if(l>r) swap(l,r);
            node ans=TQurey(0,2*n-1,l,r,1);
            if(cr&&ans.be==ans.nd&&ans.cs>1) ans.cs--;
            return ans.cs;
        }
        inline int Color(int p) {
            return TColor(p,0,2*n-1,1);
        }
    }
    #define ST SegmentTree
    
    int main() {
        scanf("%d%d",&n,&c);
        for(int i=0;i<n;i++) scanf("%d",&cl[i]);
        for(int i=0;i<n;i++) cl[n+i]=cl[i];
        ST::_init(0,(n<<1)-1,1);
        scanf("%d",&q);
        for(int a,b,c,i=1;i<=q;i++) {
            scanf("%s",qe);
            if(qe[0]=='R') {scanf("%d",&a);Tv=((Tv-a)%n+n)%n;}
            else if(qe[0]=='F') {Tf^=1;Tv=((-Tv)%n+n)%n;}
            else if(qe[0]=='C') {
                if(qe[1]=='S') {
                    scanf("%d%d",&a,&b);a--;b--;
                    a=Tran(a);b=Tran(b);if(Tf) swap(a,b);
                    if(b<a) b+=n;
                    printf("%d
    ",ST::Qurey(a,b,0));
                }
                else printf("%d
    ",ST::Qurey(0,n-1,1));
            }
            else if(qe[0]=='P') {
                scanf("%d%d%d",&a,&b,&c);a--;b--;
                a=Tran(a);b=Tran(b);if(Tf) swap(a,b);
                if(b<a) b+=n;
                ST::Print(0,2*n-1,a,b,1,c);
                if(b+n<2*n) ST::Print(0,2*n-1,a+n,b+n,1,c);
                else {
                    ST::Print(0,2*n-1,a+n,2*n-1,1,c);
                    ST::Print(0,2*n-1,0,(b+n)%n,1,c);
                }
            }
            else if(qe[0]=='S') {
                scanf("%d%d",&a,&b);a--;b--;
                a=Tran(a);b=Tran(b);
                int t1=ST::Color(a),t2=ST::Color(b);
                ST::Print(0,2*n-1,a,a,1,t2);if(a+n<2*n) ST::Print(0,2*n-1,a+n,a+n,1,t2);
                ST::Print(0,2*n-1,b,b,1,t1);if(b+n<2*n) ST::Print(0,2*n-1,b+n,b+n,1,t1);
            }
            /*
            for(int i=0;i<2*n;i++) {
                printf("%d ",ST::Color(Tran(i)));
            }
            cout<<endl;
            */
        }
        return 0;
    }
    #undef ST
    /*
    7 4
    1 3 3 3 3 1 1
    100
    F
    R 2
    P 1 7 1
    */
  • 相关阅读:
    LeetCode 动态规划专题
    LeetCode 双指针、滑动窗口、单调队列专题
    LeetCode 单调栈专题
    LeetCode DFS搜索与回溯专题
    LeetCode树专题
    操作系统思维导图| IO管理篇
    2020-为什么换了工作
    深入浅出Spring MVC
    rocketmq初识
    线上故障处理手册
  • 原文地址:https://www.cnblogs.com/ihopenot/p/6165620.html
Copyright © 2011-2022 走看看