zoukankan      html  css  js  c++  java
  • BZOJ3173: [Tjoi2013]最长上升子序列 Treap 平衡树

    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

    用Treap维护一下队列的信息,然后直接做就好。膜拜KuribohG

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstdlib>
     4 #include <algorithm>
     5 using namespace std;
     6 const int MAXN=1000001;
     7 struct Treap
     8 {
     9     int ch[2],dat,key,size,tms;
    10 }treap[MAXN];
    11 int tot,root,cnt,a[MAXN],dp[MAXN],c[MAXN],ans[MAXN],n;
    12 inline int cmp(int x,int tar)
    13 {
    14     if(treap[x].dat==tar) return -1;
    15     return (treap[x].dat<tar?0:1);
    16 }
    17 inline void maintain(int x)
    18 {
    19     treap[x].size=treap[treap[x].ch[0]].size+treap[treap[x].ch[1]].size+1;
    20 }
    21 inline int rotate(int &x,int d)
    22 {
    23     int p=treap[x].ch[d^1];
    24     treap[x].ch[d^1]=treap[p].ch[d];
    25     treap[p].ch[d]=x;
    26     maintain(x);
    27     maintain(p);
    28     x=p;
    29 }
    30 void ins(int &x,int m,int tar)
    31 {
    32     if(!x)
    33     {
    34         tot++;
    35         treap[tot].key=rand(); treap[tot].size=1; treap[tot].tms=1; treap[tot].dat=tar; x=tot;
    36         return;
    37     }
    38     int d;
    39     if(m<=treap[treap[x].ch[0]].size) ins(treap[x].ch[0],m,tar),d=0;
    40     else ins(treap[x].ch[1],m-treap[treap[x].ch[0]].size-1,tar),d=1;
    41     if(treap[treap[x].ch[d]].key>treap[x].key) rotate(x,d^1);
    42     maintain(x);
    43 }
    44 void work(int x)
    45 {
    46     if(treap[x].ch[0]) work(treap[x].ch[0]);
    47     a[++n]=treap[x].dat;
    48     if(treap[x].ch[1]) work(treap[x].ch[1]);
    49 }
    50 int main(int argc, char *argv[])
    51 {
    52     int i,x;
    53     scanf("%d",&n);
    54     for(i=1,x;i<=n;i++) {
    55         scanf("%d",&x);
    56         ins(root,x,i);
    57     }
    58     n=0;
    59     work(root);
    60     for(i=1;i<=n;i++)
    61     c[i]=n+1;
    62     for(i=1;i<=n;i++)
    63     {
    64         int sub=lower_bound(c,c+n+1,a[i])-c;
    65         dp[i]=sub;
    66         c[dp[i]]=min(c[dp[i]],a[i]);
    67         ans[a[i]]=dp[i];
    68     }
    69     for(i=1;i<=n;i++) ans[i]=max(ans[i],ans[i-1]);
    70     for(i=1;i<=n;i++) printf("%d
    ",ans[i]);
    71     return 0;
    72 }
  • 相关阅读:
    Java实现 LeetCode 394 字符串解码
    Java实现 LeetCode 394 字符串解码
    Java实现 LeetCode 392 判断子序列
    Java实现 LeetCode 392 判断子序列
    Java实现 LeetCode 392 判断子序列
    Java实现 LeetCode 391 完美矩形
    Java实现 LeetCode 391 完美矩形
    Java实现 LeetCode 391 完美矩形
    Java实现 LeetCode 390 消除游戏
    Java实现 LeetCode 390 消除游戏
  • 原文地址:https://www.cnblogs.com/BeyondW/p/5732304.html
Copyright © 2011-2022 走看看