[Tjoi2013]最长上升子序列

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

题解:

splay,按位置维护,先加入的点小,后加的大

每次加入直接模拟splay的插入。

由于没有延迟标记,所以不需要pushdown,但要pushup

每次pushup要维护两个值,当前节点结尾的最长上升子序列,当前子树的最长子序列

推测可知,当前节点结尾的最长上升子序列只由左节点子树的序列的递推而来,因为左子树位置在前面,且小

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;
 6 const int MAXN=500010;
 7 int tot2,tot1,s[MAXN],pre[MAXN],ch[MAXN][2],key[MAXN];
 8 int size[MAXN],root,n,m,maxn[MAXN],g[MAXN];
 9 void NewNode(int &x,int fa,int k)
10 {
11     if (tot2) x=s[tot2--];
12     else x=++tot1;
13     key[x]=k;
14     size[x]=1;
15     pre[x]=fa;
16     ch[x][0]=ch[x][1]=0;
17 }
18 void pushup(int x)
19 {
20     int lson=ch[x][0],rson=ch[x][1];
21     size[x]=size[lson]+size[rson]+1;
22     maxn[x]=max(max(g[x],maxn[rson]),maxn[lson]);
23     if (key[x]==2e9||key[x]==0) maxn[x]=0,g[x]=0;
24 }
25 void rotate(int x,bool t)
26 {
27     int y=pre[x];
28     ch[y][!t]=ch[x][t];
29     pre[ch[x][t]]=y;
30     if (pre[y])
31         ch[pre[y]][ch[pre[y]][1]==y]=x;
32     pre[x]=pre[y];
33     ch[x][t]=y;
34     pre[y]=x;
35     pushup(y);pushup(x);
36 }
37 int getkth(int r,int k)
38 {
39     int x=size[ch[r][0]]+1;
40     if (k==x) return r;
41     if (k<x) getkth(ch[r][0],k);
42     else getkth(ch[r][1],k-x);
43 }
44 void splay(int x,int goal)
45 {
46     while (pre[x]!=goal)
47     {
48         if (pre[pre[x]]==goal)
49         {
50             rotate(x,ch[pre[x]][0]==x);
51         }
52         else
53         {
54             int y=pre[x],kind=ch[pre[y]][0]==y;
55             if (ch[y][kind]==x)
56             {
57                 rotate(x,!kind);
58                 rotate(x,kind);
59             }
60             else
61             {
62                 rotate(y,kind);
63                 rotate(x,kind);
64             }
65         }
66     }
67     pushup(x);
68     if (goal==0) root=x;
69 }
70 int main()
71 {int i,x;
72     cin>>n;
73     NewNode(root,0,2e9);
74     NewNode(ch[root][1],root,0);
75     for (i=1; i<=n; i++)
76     {
77         scanf("%d",&x);
78         splay(getkth(root,x+1),0);
79         splay(getkth(root,x+2),root);
80         NewNode(ch[ch[root][1]][0],ch[root][1],i);
81         splay(ch[ch[root][1]][0],0);
82         g[root]=maxn[ch[root][0]]+1;
83         pushup(root);
84         printf("%d\n",maxn[root]);
85     }
86 }

 

posted @ 2017-07-19 19:58  Z-Y-Y-S  阅读(301)  评论(0编辑  收藏  举报