zoukankan      html  css  js  c++  java
  • hdu-1890-Robotic Sort splay区间翻转

    题意:

    依次找第i大的数下标pos[i],然后将区间[i,pos[i]]翻转

    分析:

    splay树区间翻转

    // File Name: ACM/HDU/1890.cpp
    // Author: Zlbing
    // Created Time: 2013年08月10日 星期六 20时26分39秒
    
    #include<iostream>
    #include<string>
    #include<algorithm>
    #include<cstdlib>
    #include<cstdio>
    #include<set>
    #include<map>
    #include<vector>
    #include<cstring>
    #include<stack>
    #include<cmath>
    #include<queue>
    using namespace std;
    #define CL(x,v); memset(x,v,sizeof(x));
    #define INF 0x3f3f3f3f
    #define LL long long
    #define REP(i,r,n) for(int i=r;i<=n;i++)
    #define RREP(i,n,r) for(int i=n;i>=r;i--)
    #define L ch[x][0]  
    #define R ch[x][1]  
    #define KT (ch[ ch[rt][1] ][0])  
    const int MAXN = 100010;  
    int cmp(pair<int,int> a,pair<int,int> b){  
            if(a.first!=b.first) return a.first<b.first;  
            return a.second < b.second;  
    }  
    int mp[MAXN];
    int id[MAXN];
    pair<int,int> num[MAXN];
    struct SplayTree {  
        int sz[MAXN];  
        int ch[MAXN][2];  
        int pre[MAXN];  
        int rt,top;  
        inline void down(int x){  
            if(flip[x]) {  
                flip[ L ] ^= 1;  
                flip[ R ] ^= 1;  
                swap(L,R);  
                flip[x]=0;  
            }  
        }  
        inline void up(int x){  
            sz[x]=1+sz[ L ] + sz[ R ];  
        }  
        inline void Rotate(int x,int f){  
            int y=pre[x];  
            down(y);  
            down(x);  
            ch[y][!f] = ch[x][f];  
            pre[ ch[x][f] ] = y;  
            pre[x] = pre[y];  
            if(pre[x]) ch[ pre[y] ][ ch[pre[y]][1] == y ] =x;  
            ch[x][f] = y;  
            pre[y] = x;  
            up(y);  
        }  
        inline void Splay(int x,int goal){//将x旋转到goal的下面  
            down(x);//防止pre[x]就是目标点,下面的循环就进不去了,x的信息就传不下去了  
            while(pre[x] != goal){  
                down(pre[pre[x]]); down(pre[x]);down(x);//在旋转之前需要先下传标记,因为节点的位置可能会发生改变  
                if(pre[pre[x]] == goal) Rotate(x , ch[pre[x]][0] == x);  
                else   {  
                    int y=pre[x],z=pre[y];  
                    int f = (ch[z][0]==y);  
                    if(ch[y][f] == x) Rotate(x,!f),Rotate(x,f);  
                    else Rotate(y,f),Rotate(x,f);  
                }  
            }  
            up(x);  
            if(goal==0) rt=x;  
        }  
        inline void RTO(int k,int goal){//将第k位数旋转到goal的下面  
            int x=rt;  
            down(x);  
            while(sz[ L ]+1 != k) {  
                if(k < sz[ L ] + 1 ) x=L;  
                else {  
                    k-=(sz[ L ]+1);  
                    x = R;  
                }  
                down(x);  
            }  
            Splay(x,goal);  
        }  
        void vist(int x){  
            if(x){  
                printf("结点%2d : 左儿子  %2d   右儿子  %2d   %2d  flip:%d
    ",x,L,R,val[x],flip[x]);  
                vist(L);  
                vist(R);  
            }  
        }  
        void Newnode(int &x,int c,int f){  
            x=++top;flip[x]=0;  
            L = R = 0;  pre[x] = f;  
            sz[x]=1; val[x]=c;  
        }  
        inline void build(int &x,int l,int r,int f){  
            if(l>r) return ;  
            int m=(l+r)>>1;  
            Newnode(x,num[id[m]].first,f);  
            mp[id[m]]=x;  
            build(L , l , m-1 , x);  
            build(R , m+1 , r , x);  
            pre[x]=f;  
            up(x);  
        }  
          
        inline void init(){  
            ch[0][0]=ch[0][1]=pre[0]=sz[0]=0;  
            rt=top=0; flip[0]=0; val[0]=0;  
        }  
        void Del(){  
             int t=rt;  
             if(ch[rt][1]) {  
                 rt=ch[rt][1];  
                 RTO(1,0);  
                 ch[rt][0]=ch[t][0];  
                 if(ch[rt][0]) pre[ch[rt][0]]=rt;  
             }  
             else rt=ch[rt][0];  
             pre[rt]=0;  
             up(rt);  
        }  
        int flip[MAXN];  
        int val[MAXN];  
    }spt;  
    int main()
    {
        int n;
        while(~scanf("%d",&n))
        {
            if(!n)break;
            spt.init();
            REP(i,1,n)
            {
                scanf("%d",&num[i].first);
                num[i].second=i;
            }
            sort(num+1,num+n+1,cmp);
            REP(i,1,n)
                id[num[i].second]=i;
            spt.build(spt.rt,1,n,0);
    
            REP(i,1,n)
            {
                spt.Splay(mp[i],0);
                int ans=i+spt.sz[spt.ch[spt.rt][0]];
                spt.flip[spt.ch[spt.rt][0]]^=1;
                spt.Del();
                if(i==1)printf("%d",ans);
                else printf(" %d",ans);
            }
            printf("
    ");
        }
        return 0;
    }
  • 相关阅读:
    eclipse中的Invalid text string (xxx).
    在jsp文件中出现Unknown tag (c:out)
    eclipse 界面复原
    ecilpse 纠错插件
    Multiple annotations found at this line:- The superclass "javax.servlet.http.HttpServlet" was not found on the Java Build Path
    Port 8080 required by Tomcat v9.0 Server at localhost is already in use. The server may already be running in another process, or a system process may be using the port.
    调用第三方https接口
    调用第三方http接口
    创建带值枚举
    spring整合redis之Redis配置文件
  • 原文地址:https://www.cnblogs.com/arbitrary/p/3250715.html
Copyright © 2011-2022 走看看