题意:依次插入i到pos[i],查询插入后当前LIS。
思路:splay。因为插入的数是升序的,那么对于i,只要知道pos[i]之前的最大LIS---x,那么以i结尾的最大LIS=x+1。那么只要在splay
中,只要维护一个当前区间最大的LIS,插入的时候,把第pos-1位的点旋到根root,把pos位的点旋到根的右结点R(root),新插入的
点插在L(R(root))即可,结点的值max(L(root)->Max,root->val)+1。注意push_up就可以了。详见代码:
/*********************************************************
file name: hdu3564.cpp
author : kereo
create time: 2015年01月29日 星期四 15时49分52秒
*********************************************************/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<set>
#include<map>
#include<vector>
#include<stack>
#include<cmath>
#include<string>
#include<algorithm>
using namespace std;
typedef long long ll;
const int sigma_size=26;
const int N=100+50;
const int MAXN=100000+50;
const int inf=0x3fffffff;
const double eps=1e-8;
const int mod=100000000+7;
#define L(x) (x->ch[0])
#define R(x) (x->ch[1])
#define PII pair<int, int>
#define mk(x,y) make_pair((x),(y))
int n,cnt,top;
int st[MAXN];
struct node{
int val,sz,Max;
node *fa,*ch[2];
}nod[MAXN],nil,*root,*null;
struct Splay{
void rotate(node *x,int d){
node *y=x->fa;
//push_down(y); push_down(x);
y->ch[d^1]=x->ch[d];
if(x->ch[d]!=null)
x->ch[d]->fa=y;
x->fa=y->fa;
if(y->fa!=null){
int d1=y->fa->ch[0] == y ? 0 : 1;
y->fa->ch[d1]=x;
}
x->ch[d]=y; y->fa=x;
push_up(y);
}
void splay(node *x,node *fa){
while(x->fa!=fa){
//push_down(x);
node *y=x->fa;
if(y->fa == fa){
int d=y->ch[0] == x ? 1 : 0;
rotate(x,d);
}
else{
int d=y->fa->ch[0] == y ? 1 : 0;
if(y->ch[d] == x){
rotate(x,d^1); rotate(x,d);
}
else{
rotate(y,d); rotate(x,d);
}
}
}
push_up(x);
if(fa == null) root=x;
}
void rotateto(int k,node *fa){
node *rt=root;
//push_down(rt);
while(L(rt)->sz!=k){
if(L(rt)->sz>k)
rt=L(rt);
else{
k-=(L(rt)->sz+1);
rt=R(rt);
}
}
//printf("rt=%d fa=%d,L(rt)->sz=%d R(rt)->sz=%d\n",rt-nod,fa-nod,L(rt)->sz,R(rt)->sz);
splay(rt,fa);
}
//----------------------------------------------//
void init(){
cnt=top=0;
nil.sz=nil.val=nil.Max=0;
nod[0].sz=nod[0].val=nod[0].Max=0;
null=&nod[0]; root=&nod[0];
newnode(root,null,0);
newnode(R(root),root,0);
push_up(root);
//printf("root->sz=%d root->val=%d\n",root->sz,root->val);
}
void newnode(node *&x,node *fa,int val){
if(top)
x=&nod[st[--top]];
else
x=&nod[++cnt];
x->sz=1; x->val=x->Max=val;
x->fa=fa; L(x)=R(x)=null;
}
void push_up(node *rt){
rt->sz=L(rt)->sz+R(rt)->sz+1;
rt->Max=max(rt->val,max(L(rt)->Max,R(rt)->Max));
}
void insert(int pos){
rotateto(pos-1,null);
rotateto(pos,root);
//printf("pos=%d root=%d\n",pos,root-nod);
newnode(L(R(root)),R(root),max(L(root)->Max,root->val)+1);
//printf("L(R(root))->val=%d L(R(root))->Max=%d\n",L(R(root))->val,L(R(root))->Max);
push_up(R(root)); push_up(root);
printf("%d\n",root->Max);
}
}spt;
int main(){
//freopen("in.txt","r",stdin);
int T,kase=0;
scanf("%d",&T);
while(T--){
spt.init();
printf("Case #%d:\n",++kase);
scanf("%d",&n);
for(int i=1;i<=n;i++){
int x;
scanf("%d",&x);
x++;
spt.insert(x);
}
printf("\n");
}
return 0;
}