用翻转对区间排序,建一个splay为1,2,...n,搞一个结构体数组A[maxn],first保存key,second保存在初始数组中的下标,按照key排个序,则A[i].second就是第i大的元素在splay中的编号,每次将其旋转到跟,比他小的元素加上i就是此时他在元素中的位置,输出后删除树根(因为这一部分已经有序啦,不删除会对后面的操作有影响)。翻转最好一次翻转两层,开始我只翻转一层就超时了。
代码:
/************************************************************************* > File Name: Spaly.cpp > Author: acvcla > QQ: > Mail: acvcla@gmail.com > Created Time: 2014Äê11ÔÂ16ÈÕ ÐÇÆÚÈÕ 00ʱ14·Ö26Ãë ************************************************************************/ #include<iostream> #include<algorithm> #include<cstdio> #include<vector> #include<cstring> #include<map> #include<queue> #include<stack> #include<string> #include<cstdlib> #include<ctime> #include<set> #include<math.h> using namespace std; typedef long long LL; const int maxn = 1e5 + 100; #define rep(i,a,b) for(int i=(a);i<=(b);i++) #define pb push_back int ch[maxn][2],pre[maxn],siz[maxn],rev[maxn]; int root,tot; struct node { int first,second; bool operator < (const node &a)const{ if(first==a.first)return second<a.second; return first<a.first; } }; node A[maxn]; inline void newnode(int &x,int fa,int id) { x=id; siz[x]=1; pre[x]=fa; ch[x][1]=ch[x][0]=0; } void update_rev(int r) { if(!r)return; swap(ch[r][0],ch[r][1]); rev[r]^=1; } void push_down(int r) { if(rev[r]) { update_rev(ch[r][0]); update_rev(ch[r][1]); rev[r]=0; } } inline void push_up(int x) { siz[x]=siz[ch[x][0]]+siz[ch[x][1]]+1; } inline void Rotate(int x,int kind) { int y=pre[x]; push_down(y); push_down(x); ch[y][!kind]=ch[x][kind]; pre[ch[x][kind]]=y; ch[x][kind]=y; if(pre[y])ch[pre[y]][ch[pre[y]][1]==y]=x; pre[x]=pre[y]; pre[y]=x; push_up(y); push_up(x); } inline void Splay(int x,int goal) { while(pre[x]!=goal){ if(pre[pre[x]]==goal)Rotate(x,ch[pre[x]][0]==x); else{ int y=pre[x]; int kind=(ch[pre[y]][0]==y); if(ch[y][kind]==x){ Rotate(x,!kind); Rotate(x,kind); }else{ Rotate(y,kind); Rotate(x,kind); } } } if(goal==0)root=x; } int Get_max(int x) { push_down(x); while(ch[x][1]){ x=ch[x][1]; push_down(x); } return x; } inline void remove_root(){ push_down(root); if(!ch[root][0]){ root=ch[root][1]; }else{ int t=Get_max(ch[root][0]); Splay(t,root); ch[t][1]=ch[root][1]; pre[ch[root][1]]=t; root=t; } pre[root]=0; push_up(root); } inline void built(int &x,int L,int R,int fa) { if(L>R)return; int mid=(R+L)>>1; newnode(x,fa,mid); built(ch[x][0],L,mid-1,x); built(ch[x][1],mid+1,R,x); push_up(x); } inline void init(int n) { pre[0]=siz[0]=0; root=tot=ch[0][0]=ch[0][1]=0; for(int i=1;i<=n;i++){ scanf("%d",&A[i].first); A[i].second=i; } sort(A+1,A+1+n); built(root,1,n,0); } int main(int argc, char const *argv[]) { int n; while(~scanf("%d",&n)&&n){ init(n); rep(i,1,n-1){ Splay(A[i].second,0); update_rev(ch[root][0]); printf("%d ",i+siz[ch[root][0]]); remove_root(); } printf("%d\n",n); } return 0; }
原文地址:http://blog.csdn.net/acvcla/article/details/41660861