BZOJ3173:[TJOI2013]最长上升子序列(Splay)

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

 

Solution

设$f[i]$表示以$i$数字为结尾的最长上升子序列长度。

可以发现插入一个数的时候只有当前这个数的$f$会变化,也就是当前这个数前面一段的$max(f)+1$。

用$Splay$维护一下就好了。

Code

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #define N (100009)
 5 using namespace std;
 6 
 7 int n,m,p,ans,Root;
 8 int Father[N],Son[N][2],f[N],Max[N],Size[N];
 9 
10 inline int read()
11 {
12     int x=0,w=1; char c=getchar();
13     while (c<'0' || c>'9') {if (c=='-') w=-1; c=getchar();}
14     while (c>='0' && c<='9') x=x*10+c-'0', c=getchar();
15     return x*w;
16 }
17 
18 int Get(int x)
19 {
20     return Son[Father[x]][1]==x;
21 }
22 
23 void Pushup(int x)
24 {
25     Max[x]=f[x];
26     if (Son[x][0]) Max[x]=max(Max[x],Max[Son[x][0]]);
27     if (Son[x][1]) Max[x]=max(Max[x],Max[Son[x][1]]);
28     Size[x]=Size[Son[x][0]]+Size[Son[x][1]]+1;
29 }
30 
31 void Rotate(int x)
32 {
33     int wh=Get(x);
34     int fa=Father[x],fafa=Father[fa];
35     if (fafa) Son[fafa][Son[fafa][1]==fa]=x;
36     Father[fa]=x; Son[fa][wh]=Son[x][wh^1];
37     if (Son[fa][wh]) Father[Son[fa][wh]]=fa;
38     Father[x]=fafa; Son[x][wh^1]=fa;
39     Pushup(fa); Pushup(x);
40 }
41 
42 void Splay(int x,int tar)
43 {
44     for (int fa; (fa=Father[x])!=tar; Rotate(x))
45         if (Father[fa]!=tar) Rotate(Get(fa)==Get(x)?fa:x);
46     if (!tar) Root=x;
47 }
48 
49 int Next(int now)
50 {
51     if (!Son[now][1]) return now;
52     now=Son[now][1];
53     while (Son[now][0]) now=Son[now][0];
54     return now;
55 }
56 
57 int Findkth(int x)
58 {
59     int now=Root;
60     while (1)
61         if (x<=Size[Son[now][0]]) now=Son[now][0];
62         else
63         {
64             x-=Size[Son[now][0]];
65             if (x==1) {Splay(now,0); return now;}
66             x--; now=Son[now][1];
67         }
68 }
69 
70 int main()
71 {
72     n=read();
73     Max[1]=Max[n+2]=f[1]=f[n+2]=-2e9;
74     Father[n+2]=1; Son[1][1]=n+2;
75     for (int i=2; i<=n+2; ++i) Size[i]=1;
76     Size[1]=2; Root=1;
77     for (int i=2; i<=n+1; ++i)
78     {
79         p=read(); p=Findkth(p+1);
80         int nxt=Next(Root);
81         
82         Splay(1,0);
83         if (nxt!=1) Splay(nxt,1);
84         f[i]=Max[Son[nxt][0]]+1;
85         ans=max(ans,f[i]);
86         printf("%d\n",ans);
87         
88         Splay(p,0);
89         if (nxt!=p) Splay(nxt,p);
90         Father[i]=nxt; Son[nxt][0]=i;
91         Max[i]=f[i];
92         Splay(i,0);
93     }
94 }

 

posted @ 2019-02-11 16:36  Refun  阅读(233)  评论(0编辑  收藏  举报