用翻转对区间排序,建一个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