Nonsense Time

Nonsense Time

時間限制: 10 Sec  內存限制: 128 MB

題目描述

You a given a permutation p1,p2,…,pn of size n. Initially, all elements in p are frozen. There will be n stages that these elements will become available one by one. On stage i, the element pki will become available.

For each i, find the longest increasing subsequence among available elements after the first i stages.

輸入

The first line of the input contains an integer T(1≤T≤3), denoting the number of test cases.
In each test case, there is one integer n(1≤n≤50000) in the first line, denoting the size of permutation.
In the second line, there are n distinct integers p1,p2,...,pn(1≤pi≤n), denoting the permutation.
In the third line, there are n distinct integers k1,k2,...,kn(1≤ki≤n), describing each stage.
It is guaranteed that p1,p2,...,pn and k1,k2,...,kn are generated randomly.

輸出

For each test case, print a single line containing n integers, where the i-th integer denotes the length of the longest increasing subsequence among available elements after the first i stages.

樣例輸入

1
5
2 5 3 1 4
1 4 5 3 2

樣例輸出

1 1 2 3 3

題意:有一個數列, 一開始這些數都不可用,接下來每次會讓一個位置上的數變得可用,求每次操做後可用數的LIS。
思路:前置知識:長度爲N的全排列的LIS的指望爲sqrt(N),因而能夠倒着讓這些數變得不可用,若是它不是LIS上的數就對答案沒影響,不然就暴力從新nlogn跑LIS。由於LIS的指望長度爲sqrt(N),因此刪除某一個數,該數是LIS上的數的機率是1/sqrt(N),也就是說指望會有sqrt(N)個數在LIS上,因而咱們最多跑sqrt(N)遍暴力,指望複雜度:O(n*sqrt(n)*log(n))。
#include<bits/stdc++.h>
using namespace std;
const int N = 50050;
int arr[N],b[N]={0},len;
int k[N],vis[N]={0};
int pre[N];
int if_lis[N],id[N];

int Serach(int num,int low,int high)
{
    int mid;
    while (low<=high) {
        mid=(low+high)>>1;
        if (num>=b[mid]) low=mid+1;
        else high=mid-1;
    }
    return low;
}

void DP(int n)
{
    len=0;
    b[len]=-1;
    id[len]=-1;
    for(int i=1;i<=n;i++)
    {
        if(!vis[i])continue;
        if(arr[i]>=b[len])
        {
            len++;
            b[len]=arr[i];

            id[len]=i;
            pre[i]=id[len-1];
        }
        else
        {
            int pos=Serach(arr[i],1,len);
            b[pos]=arr[i];

            pre[i]=id[pos-1];
            id[pos]=i;
        }
    }

    memset(if_lis,0,sizeof(if_lis));
    int now=id[len];
    while(now!=-1)
    {
        if_lis[now]=1;
        now=pre[now];
    }
}

int ans[N];
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int n;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)scanf("%d",&arr[i]);
        for(int i=1;i<=n;i++)scanf("%d",&k[i]);
        for(int i=1;i<=n;i++)vis[i]=1;

        DP(n);
        ans[n]=len;

        for(int i=n-1;i>=1;i--)
        {
            vis[k[i+1]]=0;
            if(!if_lis[k[i+1]])
            {
                ans[i]=ans[i+1];
                continue;
            }
            DP(n);
            ans[i]=len;
        }
        for(int i=1;i<=n;i++)printf("%d%c",ans[i],i==n ? '\n' : ' ');
    }
    return 0;
}
View Code
相關文章
相關標籤/搜索