题意:依次插入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; }
时间: 2024-10-14 19:00:53