• bzoj3173


    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

     
     
    因为后面插入的数一定比前面的大, 所以更后插入的对当前的答案没有任何影响,所以预处理出每个数的最终位置,然后动态规划即可。
    时间复杂度O(nlogn)
     1 #include<stdio.h>
     2 #include<stdlib.h>
     3 #include<string>
     4 #include<string.h>
     5 #include<iostream>
     6 #include<algorithm>
     7 #include<queue>
     8 #include<math.h>
     9 #include<vector>
    10 #include<map>
    11 #include<set>
    12 #define il inline
    13 #define re register
    14 using namespace std;
    15 const int N=1000001;
    16 int l[N],r[N],rnd[N],siz[N],v[N],s[N],cnt,now,root,n,ans[N],g;
    17 il void update(re int k){
    18     siz[k]=siz[l[k]]+siz[r[k]]+1;
    19 }
    20 il void rturn(re int &k){
    21     int t=l[k];l[k]=r[t];r[t]=k;update(k);update(t);k=t;
    22 }
    23 il void lturn(re int &k){
    24     int t=r[k];r[k]=l[t];l[t]=k;update(k);update(t);k=t;
    25 }
    26 il void insert(re int &k,re int rank){
    27     if(!k){
    28         k=(++cnt);rnd[k]=rand();siz[k]=1;return;
    29     }
    30     siz[k]++;
    31     if(siz[l[k]]<rank){
    32         insert(r[k],rank-siz[l[k]]-1);
    33         if(rnd[r[k]]<rnd[k]) lturn(k);
    34     }
    35     else{
    36         insert(l[k],rank);
    37         if(rnd[l[k]]<rnd[k]) rturn(k);
    38     }
    39 }
    40 il int read(){
    41     re int hs=0;re char c=getchar();
    42     while(!isdigit(c)) c=getchar();
    43     while(isdigit(c)){
    44         hs=(hs<<3)+(hs<<1)+c-'0';
    45         c=getchar();
    46     }
    47     return hs;
    48 }
    49 il void dfs(re int k){
    50     if(!k) return;
    51     dfs(l[k]);
    52     v[++now]=k;
    53     dfs(r[k]);
    54 }
    55 int main(){
    56     memset(s,127,sizeof(s));s[0]=-1000000000;n=read();
    57     for(re int i=1,x;i<=n;i++){
    58         x=read();insert(root,x);
    59     }
    60     dfs(root);
    61     for(re int i=1,t;i<=n;i++){
    62         t=upper_bound(s,s+g+1,v[i])-s;
    63         if(s[t-1]<=v[i]){
    64             s[t]=min(s[t],v[i]);
    65             ans[v[i]]=t;
    66             g=max(g,t);
    67         }
    68     }
    69     for(re int i=1;i<=n;i++){
    70         ans[i]=max(ans[i-1],ans[i]);
    71         printf("%d
    ",ans[i]);
    72     }
    73     return 0;
    74 }
  • 相关阅读:
    wonderful life
    .net 4.5 webform 提取ModelState错误信息
    asp.net core Theme 中间件
    asp.net mvc 动态编译生成Controller
    asp.net mvc中换肤机制类库 ThemedViewEngines
    vs code 添加jquery的智能提示
    vs2017 iisexpress 绑定自定义域名
    asp.net Mvc 动态创建Controller
    查询Windows api
    预先创建占用一定磁盘空间的文件(使用C#)
  • 原文地址:https://www.cnblogs.com/ExiledPoet/p/5802245.html
Copyright © 2020-2023  润新知