BZOJ3173: [Tjoi2013]最长上升子序列

Time Limit: 10 Sec  Memory Limit: 128 MB
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

/**************************************************************

    Problem: 3173

    User: ictsing

    Language: C++

    Result: Accepted

    Time:848 ms

    Memory:4808 kb

****************************************************************/

 

//BZOJ3173 [Tjoi2013]最长上升子序列

#include <iostream>

#include <cstdio>

#include <cstdlib>

#include <algorithm>

#include <cstring>

using namespace std;

int root=0,tot=0;

const int mt = 100000+5;

const int inf = 1000000000;

int ls[mt],rs[mt],rnd[mt],sz[mt],w[mt];

int dp[mt];

int cnt=0;

int val[mt];

inline int read()

{

    int num=0,flag=1;

    char ch;

    do{

       ch=getchar();

       if(ch=='-') flag=-1;

    }while(ch<'0'||ch>'9');

    do{

       num=num*10+ch-'0';

       ch=getchar();

    }while(ch>='0'&&ch<='9');

    return num*flag;

}

void update(int rt)

{

    sz[rt]=sz[ls[rt]]+sz[rs[rt]]+w[rt];

}

void lturn(int &k)

{

    int t=rs[k];

    rs[k]=ls[t];

    ls[t]=k;

    update(k);

    update(t);    

    k=t;

}

void rturn(int &k)

{

    int t=ls[k];

    ls[k]=rs[t];

    rs[t]=k;

    update(k);

    update(t);

    k=t;

}   

void insrt(int &rt,int x)

{

    if(!rt)

    {

        rt=++tot;

        sz[rt]=w[rt]=1;

        rnd[rt]=rand();

        ls[rt]=rs[rt]=0;

        return ;

    }

    sz[rt]++;

    if(sz[ls[rt]]>=x)

    {

        insrt(ls[rt],x);

        if(rnd[ls[rt]]<rnd[rt]) rturn(rt);

    }

    else

    {

        insrt(rs[rt],x-sz[ls[rt]]-w[rt]);

        if(rnd[rs[rt]]<rnd[rt]) lturn(rt);

    }

}

int qwq=0;

void dfs(int rt)

{

    if(!rt) return ;

    if(ls[rt])  dfs(ls[rt]);

    val[++qwq]=rt;

    if(rs[rt]) dfs(rs[rt]);

}

int ans[mt];

int mn[mt],mx;

int main()

{

    int n=read();

    for(int i=1;i<=n;i++)

    {

        int x=read();

        insrt(root,x);

    }

    dfs(root);

    /*memset(dp,127,sizeof(dp));

    dp[0]=-inf;int mx=0;*/

    /*for(int i=1;i<=n;i++)

        cout<<val[i]<<endl;*/

    /*for(int i=1;i<=n;i++)

    {

        int t=upper_bound(dp,dp+mx+1,val[i])-dp;

        if(dp[t-1]<=val[i])

        {

            dp[t]=min(dp[t],val[i]);

            ans[val[i]]=t;

            mx=max(mx,t);

        }

    }*/

    memset(mn,127,sizeof(mn));

    mn[0]=-inf;

    for(int i=1;i<=n;i++)

    {

        int t=upper_bound(mn,mn+mx+1,val[i])-mn;

        if(mn[t-1]<=val[i])

        {

            mn[t]=min(mn[t],val[i]);

            ans[val[i]]=t;

            mx=max(t,mx);

        }

    }    

    for(int i=1;i<=n;i++)

    {

        ans[i]=max(ans[i],ans[i-1]);

        printf("%d\n",ans[i]);

    }

    return 0;

}

 



评论

热度(7)