hdu1890 Robotic Sort splay
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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++; down(r); while(k!=sz[ch[r][0]]+1){ if(k<sz[ch[r][0]]+1) r=ch[r][0]; else k-=sz[ch[r][0]]+1,r=ch[r][1]; down(r); } 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; }
以上是关于hdu1890 Robotic Sort splay的主要内容,如果未能解决你的问题,请参考以下文章
HDU1890 Robotic Sort[splay 序列]
HDU 1890 - Robotic Sort - [splay][区间反转+删除根节点]