hdu 6635 2019杭電多校六 1002 Nonsense Time

從最後一個修改往前遍歷,每次如果凍結的是記錄中的最長上升子序列,就重新暴力一遍最長上升子序列並記錄,注意記錄的時候用path,lis只能求出長度,裏面的數字不一定是最長上升子序列,複雜度因爲是隨機生成的序列,所以最長上升子序列長度平均爲sqrt(n),修改的時候正好去掉當今最長上升子序列中的數的概率不高,出題人不卡特殊數據還把時間開了14秒,所以複雜度爲n*sqrt(n)logn

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <vector>
#include <time.h>
#include <algorithm>
typedef long long ll;
using namespace std;
const ll mod=998244353;
const int maxn=1e5+100;

int n;
int p[maxn],k[maxn],ans[maxn];
int vis[maxn],path[maxn];
vector<int>lis;

int f()
{
    memset(vis,0,sizeof vis);
    memset(path,0,sizeof path);
    lis.clear();
    for(int i=1;i<=n;i++){
        if(p[i]==-1)continue;
        if(lis.size()==0 || p[i]>lis[lis.size()-1]){
            lis.push_back(p[i]);
            path[i]=lis.size();
        }
        else{
            int pos=lower_bound(lis.begin(),lis.end(),p[i])-lis.begin();
            lis[pos]=p[i];
            path[i]=pos+1;
        }
    }
    int tmp=lis.size();
    for(int i=n;i>=1;i--){
        if(tmp==0)break;
        if(path[i]==tmp){
            vis[p[i]]=1;
            tmp--;
        }
    }
    return lis.size();
}

int main() {
//    freopen("in.txt","r",stdin);
//    freopen("out.txt","w",stdout);
    int t;
    scanf("%d",&t);
    while(t--){
        scanf("%d",&n);
        for(int i=1;i<=n;i++)scanf("%d",&p[i]);
        for(int i=1;i<=n;i++)scanf("%d",&k[i]);
        ans[n]=f();
        for(int i=n-1;i>=1;i--){
            int x=p[k[i+1]];
            p[k[i+1]]=-1;
            if(vis[x]==1)ans[i]=f();
            else ans[i]=ans[i+1];
        }
        for(int i=1;i<=n;i++){
            printf("%d",ans[i]);
            printf("%c",i==n?'\n':' ');
        }
    }

    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章