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\n",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

 

转载于:https://www.cnblogs.com/--560/p/5202586.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值