zoukankan      html  css  js  c++  java
  • hdu1890 Robotic Sort splay

    先预处理编个顺序,然后用splay搞了。

    涉及的操作:区间翻转,区间最小值查询。

    //#include<bits/stdc++.h>
    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #include<map>
    #define REP(i,a,b) for(int i=a;i<=b;i++)
    #define MS0(a) memset(a,0,sizeof(a))
    #define PII pair<int,int>
    #define key_val ch[ch[rt][1]][0]
    
    using namespace std;
    
    typedef long long ll;
    const int maxn=1000100;
    const int INF=1e9+10;
    
    int n;
    int a[maxn];
    PII b[maxn];
    map<PII,int> rk;
    int L,R;
    
    struct Node
    {
        int v,id;
        friend bool operator<(Node A,Node B)
        {
            return A.v<B.v;
        }
    };Node Min[maxn],val[maxn];
    int pre[maxn],sz[maxn],ch[maxn][2],rt,tot1;
    int s[maxn],tot2;
    int rev[maxn];
    
    void debug(int r)
    {
        if(r==0) return;
        //printf("lch=%2d rch=%2d r=%2d pre=%2d sz=%2d rt=%2d val=%12d
    ",ch[r][0],ch[r][1],r,pre[r],sz[r],rt,val[r]);
        debug(ch[r][0]);
        printf("%d ",val[r]);
        debug(ch[r][1]);
    }
    void out()
    {
        debug(rt);puts("");
    }
    
    void newnode(int &r,int fa,int k)
    {
        if(tot2) r=s[tot2--];
        else r=++tot1;
        pre[r]=fa;
        rev[r]=0;
        val[r]=Min[r]={k,r};
        sz[r]=1;
        MS0(ch[r]);
    }
    
    void up(int r)
    {
        sz[r]=sz[ch[r][0]]+sz[ch[r][1]]+1;
        Min[r]=min(min(Min[ch[r][0]],Min[ch[r][1]]),val[r]);
    }
    
    void update_rev(int r)
    {
        if(!r) return;
        swap(ch[r][0],ch[r][1]);
        rev[r]^=1;
    }
    
    void down(int r)
    {
        if(rev[r]){
            update_rev(ch[r][0]);
            update_rev(ch[r][1]);
            rev[r]=0;
        }
    }
    
    void rot(int x,int kind)
    {
        int y=pre[x];
        down(y);down(x);
        ch[y][kind^1]=ch[x][kind];
        pre[ch[x][kind]]=y;
        if(pre[y]) ch[pre[y]][ch[pre[y]][1]==y]=x;
        pre[x]=pre[y];
        ch[x][kind]=y;
        pre[y]=x;
        up(y);
    }
    
    void splay(int x,int goal)
    {
        down(x);
        while(pre[x]!=goal){
            if(pre[pre[x]]==goal) rot(x,ch[pre[x]][0]==x);
            else{
                int y=pre[x],z=pre[y];
                int kind=ch[y][0]==x,one=0;
                if(ch[y][0]==x&&ch[z][0]==y) one=1;
                if(ch[y][1]==x&&ch[z][1]==y) one=1;
                if(one) rot(y,kind),rot(x,kind);
                else rot(x,kind),rot(x,kind^1);
            }
        }
        if(goal==0) rt=x;
        up(x);
    }
    
    void rto(int k,int goal)
    {
        int r=rt;k++;
        while(k!=sz[ch[r][0]]+1){
            down(r);
            if(k<sz[ch[r][0]]+1) r=ch[r][0];
            else k-=sz[ch[r][0]]+1,r=ch[r][1];
        }
        splay(r,goal);
    }
    
    void Rev(int l,int r)
    {
        rto(l-1,0);
        rto(r+1,rt);
        update_rev(key_val);
    }
    
    int query(int l,int r)
    {
        rto(l-1,0);
        rto(r+1,rt);
        return Min[key_val].id;
    }
    
    void build(int &x,int l,int r,int fa)
    {
        if(l>r) return;
        int m=(l+r)>>1;
        newnode(x,fa,a[m]);
        build(ch[x][0],l,m-1,x);
        build(ch[x][1],m+1,r,x);
        up(x);
    }
    
    void Init()
    {
        rt=tot1=tot2=0;
        pre[0]=sz[0]=ch[0][0]=ch[0][1]=rev[0]=0;
        Min[0]=val[0]={INF,0};
        newnode(rt,0,-INF);
        newnode(ch[rt][1],rt,INF);
        sz[rt]=2;
        build(key_val,1,n,ch[rt][1]);
        up(ch[rt][1]);
        up(rt);
    }
    
    void deal()
    {
        REP(i,1,n) b[i]={a[i],i};
        sort(b+1,b+n+1);
        rk.clear();
        REP(i,1,n) rk[b[i]]=i;
        REP(i,1,n) a[i]=rk[{a[i],i}];
    }
    
    int main()
    {
        //freopen("in.txt","r",stdin);
        while(cin>>n,n){
            REP(i,1,n) scanf("%d",&a[i]);
            deal();
            Init();
            REP(i,1,n){
                R=query(i,n);
                splay(R,0);
                R=sz[ch[R][0]];
                L=i;
                Rev(L,R);
                //debug(rt);puts("");
                //out();
                printf("%d",R);
                if(i!=n) printf(" ");
                else puts("");
            }
        }
        return 0;
    }
    View Code
    没有AC不了的题,只有不努力的ACMER!
  • 相关阅读:
    团队博客——Sprint计划会议1
    团队博客第一次(团队成员及团队作业说明)
    第一次冲刺-团队开发(第一天)
    cnblog评价以及团队软件的部分改善
    Sprint计划会议1
    团队开发--手机小游戏 需求分析
    团队博客和成员
    第一次冲刺01
    第二次冲刺——第二次总结
    团队开发——Alpha版总结会议
  • 原文地址:https://www.cnblogs.com/--560/p/5202586.html
Copyright © 2011-2022 走看看