• 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 }
  • 相关阅读:
    智能指针和二叉树(2):资源的自动管理
    c++智能指针和二叉树(1): 图解层序遍历和逐层打印二叉树
    QLineEdit拾遗:数据的过滤、验证和补全
    为Qt视图中的文字添加彩虹渐变效果
    python3的变量作用域规则和nonlocal关键字
    三种方法为QLineEdit添加清除内容按钮
    配置CLion作为Qt5开发环境
    c++随机排序容器中的元素
    c++性能测试工具:google benchmark入门(一)
    shared_ptr和动态数组
  • 原文地址:https://www.cnblogs.com/BeyondW/p/5732304.html
Copyright © 2020-2023  润新知