http://acm.hdu.edu.cn/showproblem.php?pid=1890
伸展树模板
博客:
https://www.cnblogs.com/wxgblogs/p/5506234.html
https://blog.csdn.net/wr132/article/details/50599747
http://www.cnblogs.com/vamei/archive/2013/03/21/2964092.html
http://dongxicheng.org/structure/splay-tree/
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
struct node1
{
int id;
int val;
};
struct node2;
node2 *null;
struct node2
{
node2 *fa,*ch[2];
int sz,rev;
void wipe()
{
fa=ch[0]=ch[1]=null;
sz=1,rev=0;
}
void setc(node2* tmp,int d)
{
ch[d]=tmp;
tmp->fa=this;
}
int getd()
{
return fa->ch[1]==this;
}
void reverse()
{
if(this==null) return;
swap(ch[0],ch[1]);
rev^=1;
}
void pushup()
{
if(this==null) return;
sz=ch[0]->sz+ch[1]->sz+1;
}
void pushdown()
{
if(this==null) return;
if(rev!=0)
{
ch[0]->reverse();
ch[1]->reverse();
rev=0;
}
}
};
node1 ary[100010];
node2* mp[100010];
node2 pool[100010];
node2 *root,*tail;
int n;
bool cmp(node1 n1,node1 n2)
{
if(n1.val==n2.val) return n1.id<n2.id;
else return n1.val<n2.val;
}
void build(node2 *&cur,int l,int r,node2 *fa)
{
int m;
if(l>r) return;
m=(l+r)/2;
cur=tail++;
cur->wipe();
cur->fa=fa;
mp[m]=cur;
build(cur->ch[0],l,m-1,cur);
build(cur->ch[1],m+1,r,cur);
cur->pushup();
}
void init()
{
node2* tmp;
int i;
tail=pool;
null=tail++;
null->fa=null->ch[0]=null->ch[1]=null;
null->sz=null->rev=0;
tmp=tail++;
tmp->wipe();
root=tmp;
tmp=tail++;
tmp->wipe();
root->setc(tmp,1);
build(root->ch[1]->ch[0],1,n,root->ch[1]);
root->ch[1]->pushup();
root->pushup();
}
void rotate(node2 *cur)
{
node2 *f,*ff;
int c,cc;
f=cur->fa,ff=cur->fa->fa;
f->pushdown();
cur->pushdown();
c=cur->getd(),cc=f->getd();
f->setc(cur->ch[!c],c);
cur->setc(f,!c);
if(ff->ch[cc]==f) ff->setc(cur,cc);
else cur->fa=ff;
f->pushup();
}
void splay(node2 *&root,node2 *cur,node2 *tar)
{
while(cur->fa!=tar)
{
if(cur->fa->fa==tar) rotate(cur);
else
{
cur->fa->fa->pushdown();
cur->fa->pushdown();
cur->pushdown();
if(cur->getd()==cur->fa->getd()) rotate(cur->fa);
else rotate(cur);
rotate(cur);
}
}
cur->pushup();
if(tar==null) root=cur;
}
node2 *getkth(node2 *r,int k)
{
node2 *cur;
cur=r;
cur->pushdown();
while(cur->ch[0]->sz+1!=k)
{
if(cur->ch[0]->sz+1>k)
{
cur=cur->ch[0];
}
else
{
k-=(cur->ch[0]->sz+1);
cur=cur->ch[1];
}
cur->pushdown();
}
return cur;
}
int main()
{
int i,sz;
while(scanf("%d",&n)!=EOF)
{
if(n==0) break;
for(i=1;i<=n;i++)
{
ary[i].id=i;
scanf("%d",&ary[i].val);
}
init();
sort(ary+1,ary+n+1,cmp);
for(i=1;i<=n;i++)
{
splay(root,mp[ary[i].id],null);
sz=root->ch[0]->sz;
printf("%d",sz);
if(i<n) printf(" ");
else printf("\n");
splay(root,getkth(root,i),null);
splay(root,getkth(root,sz+2),root);
root->ch[1]->ch[0]->reverse();
}
}
return 0;
}