您的位置:首页 > 其它

[Tjoi2013]最长上升子序列

2017-07-19 19:58 204 查看

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

[b]题解:[/b]

[b]splay,按位置维护,先加入的点小,后加的大[/b]

[b]每次加入直接模拟splay的插入。[/b]

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

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

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

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN=500010;
int tot2,tot1,s[MAXN],pre[MAXN],ch[MAXN][2],key[MAXN];
int size[MAXN],root,n,m,maxn[MAXN],g[MAXN];
void NewNode(int &x,int fa,int k)
{
if (tot2) x=s[tot2--];
else x=++tot1;
key[x]=k;
size[x]=1;
pre[x]=fa;
ch[x][0]=ch[x][1]=0;
}
void pushup(int x)
{
int lson=ch[x][0],rson=ch[x][1];
size[x]=size[lson]+size[rson]+1;
maxn[x]=max(max(g[x],maxn[rson]),maxn[lson]);
if (key[x]==2e9||key[x]==0) maxn[x]=0,g[x]=0;
}
void rotate(int x,bool t)
{
int y=pre[x];
ch[y][!t]=ch[x][t];
pre[ch[x][t]]=y;
if (pre[y])
ch[pre[y]][ch[pre[y]][1]==y]=x;
pre[x]=pre[y];
ch[x][t]=y;
pre[y]=x;
pushup(y);pushup(x);
}
int getkth(int r,int k)
{
int x=size[ch[r][0]]+1;
if (k==x) return r;
if (k<x) getkth(ch[r][0],k);
else getkth(ch[r][1],k-x);
}
void splay(int x,int goal)
{
while (pre[x]!=goal)
{
if (pre[pre[x]]==goal)
{
rotate(x,ch[pre[x]][0]==x);
}
else
{
int y=pre[x],kind=ch[pre[y]][0]==y;
if (ch[y][kind]==x)
{
rotate(x,!kind);
rotate(x,kind);
}
else
{
rotate(y,kind);
rotate(x,kind);
}
}
}
pushup(x);
if (goal==0) root=x;
}
int main()
{int i,x;
cin>>n;
NewNode(root,0,2e9);
NewNode(ch[root][1],root,0);
for (i=1; i<=n; i++)
{
scanf("%d",&x);
splay(getkth(root,x+1),0);
splay(getkth(root,x+2),root);
NewNode(ch[ch[root][1]][0],ch[root][1],i);
splay(ch[ch[root][1]][0],0);
g[root]=maxn[ch[root][0]]+1;
pushup(root);
printf("%d\n",maxn[root]);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: