zoukankan      html  css  js  c++  java
  • 区间翻转(codevs 3243)

    题目描述 Description

    给出N个数,要求做M次区间翻转(如1 2 3 4变成4 3 2 1),求出最后的序列

    输入描述 Input Description

    第一行一个数N,下一行N个数表示原始序列,在下一行一个数M表示M次翻转,之后的M行每行两个数L,R表示将区间[L,R]翻转。

    输出描述 Output Description

    一行N个数 , 表示最终序列。

    样例输入 Sample Input

    4

    1 2 3 4

    2

    1 2

    3 4

    样例输出 Sample Output

    2 1 4 3

    数据范围及提示 Data Size & Hint

    对于30%的数据满足n<=100 , m <= 10000

    对于100%的数据满足n <= 150000 , m <= 150000

    对于100%的数据满足n为2的幂,且L = i * 2^j + 1 , R = (i + 1) * 2^j

    最初自己写了一个,然后怎么调也调不出来,明天再战:

    #include<cstdio>
    #include<iostream>
    #define N 150010
    using namespace std;
    int son[N][2],fa[N],val[N],order[N],rev[N],sz[N],n,m,rt,size;
    void pushup(int x){
        if(!x)return;
        sz[x]=sz[son[x][0]]+sz[son[x][1]]+1;    
    }
    void pushdown(int x){
        swap(son[x][0],son[x][1]);
        rev[son[x][0]]^=1;rev[son[x][1]]^=1;
        rev[x]^=1;
    }
    void rotate(int x,int &k){
        int y=fa[x],z=fa[y],l,r;
        if(son[y][0]==x)l=0;else l=1;r=l^1;
        if(y==k)k=x;
        else {
            if(son[z][0]==y) son[z][0]=x;
            else son[z][1]=x;
        }
        fa[x]=z;fa[y]=x;fa[son[x][r]]=y;
        son[y][l]=son[x][r];son[x][r]=y;
        pushup(y);pushup(x);
    }
    void splay(int x,int &k){
        while(x!=k){
            int y=fa[x],z=fa[y];
            if(y!=k){
                if((son[y][0]==x)^(son[z][0]==y)) rotate(x,k);
                else rotate(y,k);
            }
            rotate(x,k);
        }
    }
    void insert(int hao,int v){
        int k=rt,y=0;
        while(k)y=k,k=son[k][hao>order[k]];
        k=++size;fa[k]=y;son[y][v>order[y]]=k;val[k]=v;order[k]=hao;sz[k]=1;
        splay(k,rt);
    }
    int find(int x){
        int k=rt;
        while(1){
            if(rev[k])pushdown(k);
            if(sz[son[k][0]]+1==x)return k;
            if(sz[son[k][0]]>=x) k=son[k][0];
            else x-=(sz[son[k][0]]+1),k=son[k][1];
        }
    }
    void rever(int x,int y){
        if(x==1&&y==n)rev[rt]^=1;
        if(x==1&&y<n){
            int p=find(y+1);
            splay(p,rt);rev[son[rt][0]]^=1;
        }
        if(y==n&&x>1){
            int p=find(x-1);
            splay(p,rt);rev[son[rt][1]]^=1;
        }
        if(x>1&&y<n){
            int p;
            p=find(x-1);splay(p,rt);
            p=find(y+1);splay(p,son[rt][1]);
            rev[son[son[rt][1]][0]]^=1;
        }
    }
    void dfs(int k){
        if(!k)return;
        if(rev[k])pushdown(k);
        dfs(son[k][0]);
        printf("%d ",val[k]);
        dfs(son[k][1]);
    }
    int main(){
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            int x;scanf("%d",&x);
            insert(i,x);
        }
        scanf("%d",&m);
        for(int i=1;i<=m;i++){
            int x,y;scanf("%d%d",&x,&y);
            //if(i==1)continue;
            rever(x,y);
        }
        dfs(rt);
        return 0;
    }

    比着黄学长写了一个:

    #include<cstdio>
    #include<iostream>
    #define N 150010
    using namespace std;
    int fa[N],son[N][2],id[N],sz[N],rev[N],val[N];
    int n,m,size,rt;
    void pushup(int k){
        int l=son[k][0],r=son[k][1];
        sz[k]=sz[l]+sz[r]+1;
    }
    void pushdown(int k){
        int l=son[k][0],r=son[k][1];
        if(rev[k]){
            swap(son[k][0],son[k][1]);
            rev[l]^=1;rev[r]^=1;
            rev[k]=0;
        }
    }
    void rotate(int x,int &k){
        int y=fa[x],z=fa[y],l,r;
        if(son[y][0]==x)l=0;else l=1;r=l^1;
        if(y==k)k=x;
        else {
            if(son[z][0]==y) son[z][0]=x;
            else son[z][1]=x;
        }
        fa[x]=z;fa[y]=x;fa[son[x][r]]=y;
        son[y][l]=son[x][r];son[x][r]=y;
        pushup(y);pushup(x);
    }
    void splay(int x,int &k){
        while(x!=k){
            int y=fa[x],z=fa[y];
            if(y!=k){
                if((son[y][0]==x)^(son[z][0]==y)) rotate(x,k);
                else rotate(y,k);
            }
            rotate(x,k);
        }
    }
    int find(int k,int rank){
        pushdown(k);
        int l=son[k][0],r=son[k][1];
        if(sz[l]+1==rank)return k;
        else if(sz[l]>=rank) return find(l,rank);
        else return find(r,rank-sz[l]-1);
    }
    void rever(int l,int r){
        int x=find(rt,l),y=find(rt,r+2);
        splay(x,rt);splay(y,son[x][1]);
        int z=son[y][0];rev[z]^=1;
    }
    void build(int l,int r,int f){
        if(l>r)return;
        int now=id[l],last=id[f];
        if(l==r){
            fa[now]=last;sz[now]=1;
            if(l<f)son[last][0]=now;
            else son[last][1]=now;
            return;
        }
        int mid=l+r>>1;now=id[mid];
        build(l,mid-1,mid);build(mid+1,r,mid);
        fa[now]=last;pushup(mid);
        if(mid<f)son[last][0]=now;
        else son[last][1]=now;
    }
    int main(){
        scanf("%d",&n);
        for(int i=1;i<=n+2;i++)
            id[i]=++size;
        val[1]=-0x7fffffff;val[n+1]=0x7fffffff;
        for(int i=2;i<=n+1;i++)
            scanf("%d",&val[i]);
        build(1,n+2,0);rt=(n+3)>>1;
        scanf("%d",&m);
        for(int i=1;i<=m;i++){
            int l,r;scanf("%d%d",&l,&r);
            rever(l,r);
        }
        for(int i=2;i<=n+1;i++)
            printf("%d ",val[find(rt,i)]);
        return 0;
    }
  • 相关阅读:
    assembly 基础
    自定义编写0号内中断除法错误的中断处理程序
    Codeforces Round #573 (Div. 2) D. Tokitsukaze, CSL and Stone Game (博弈,思维)
    Codeforces Round #573 (Div. 2) E. Tokitsukaze and Duel (博弈)
    Schedule HDU
    牛客假日团队赛5 F 随机数 BZOJ 1662: [Usaco2006 Nov]Round Numbers 圆环数 (dfs记忆化搜索的数位DP)
    洛谷 P2866 [USACO06NOV]糟糕的一天Bad Hair Day 牛客假日团队赛5 A (单调栈)
    「BZOJ1669」D 饥饿的牛 [Usaco2006 Oct] Hungry Cows 牛客假日团队赛5 (LIS,离散化树状数组)
    树状数组求LIS模板
    牛客OI周赛11-普及组 B Game with numbers (数学,预处理真因子)
  • 原文地址:https://www.cnblogs.com/harden/p/6403551.html
Copyright © 2011-2022 走看看