BZOJ3173: [Tjoi2013]最长上升子序列 Treap 平衡树

Description

给定一个序列,初始为空。现在我们将1到N的数字插入到序列中,每次将一个数字插入到一个特定的位置。每插入一个数字,我们都想知道此时最长上升子序列长度是多少?

Input

第一行一个整数N,表示我们要将1到N插入序列中,接下是N个数字,第k个数字Xk,表示我们将k插入到位置Xk(0<=Xk<=k-1,1<=k<=N)

Output

N行,第i行表示i插入Xi位置后序列的最长上升子序列的长度是多少。

Sample Input

3
0 0 2

Sample Output

1
1
2

HINT

100%的数据 n<=100000

用Treap维护一下队列的信息,然后直接做就好。膜拜KuribohG

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstdlib>
 4 #include <algorithm>
 5 using namespace std;
 6 const int MAXN=1000001;
 7 struct Treap
 8 {
 9     int ch[2],dat,key,size,tms;
10 }treap[MAXN];
11 int tot,root,cnt,a[MAXN],dp[MAXN],c[MAXN],ans[MAXN],n;
12 inline int cmp(int x,int tar)
13 {
14     if(treap[x].dat==tar) return -1;
15     return (treap[x].dat<tar?0:1);
16 }
17 inline void maintain(int x)
18 {
19     treap[x].size=treap[treap[x].ch[0]].size+treap[treap[x].ch[1]].size+1;
20 }
21 inline int rotate(int &x,int d)
22 {
23     int p=treap[x].ch[d^1];
24     treap[x].ch[d^1]=treap[p].ch[d];
25     treap[p].ch[d]=x;
26     maintain(x);
27     maintain(p);
28     x=p;
29 }
30 void ins(int &x,int m,int tar)
31 {
32     if(!x)
33     {
34         tot++;
35         treap[tot].key=rand(); treap[tot].size=1; treap[tot].tms=1; treap[tot].dat=tar; x=tot;
36         return;
37     }
38     int d;
39     if(m<=treap[treap[x].ch[0]].size) ins(treap[x].ch[0],m,tar),d=0;
40     else ins(treap[x].ch[1],m-treap[treap[x].ch[0]].size-1,tar),d=1;
41     if(treap[treap[x].ch[d]].key>treap[x].key) rotate(x,d^1);
42     maintain(x);
43 }
44 void work(int x)
45 {
46     if(treap[x].ch[0]) work(treap[x].ch[0]);
47     a[++n]=treap[x].dat;
48     if(treap[x].ch[1]) work(treap[x].ch[1]);
49 }
50 int main(int argc, char *argv[])
51 {
52     int i,x;
53     scanf("%d",&n);
54     for(i=1,x;i<=n;i++) {
55         scanf("%d",&x);
56         ins(root,x,i);
57     }
58     n=0;
59     work(root);
60     for(i=1;i<=n;i++)
61     c[i]=n+1;
62     for(i=1;i<=n;i++)
63     {
64         int sub=lower_bound(c,c+n+1,a[i])-c;
65         dp[i]=sub;
66         c[dp[i]]=min(c[dp[i]],a[i]);
67         ans[a[i]]=dp[i];
68     }
69     for(i=1;i<=n;i++) ans[i]=max(ans[i],ans[i-1]);
70     for(i=1;i<=n;i++) printf("%d\n",ans[i]);
71     return 0;
72 }

 

posted @ 2016-08-03 11:59  BeyondW  阅读(156)  评论(0编辑  收藏  举报