zoukankan      html  css  js  c++  java
  • [Tjoi2013]最长上升子序列

    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

    题解:

    splay,按位置维护,先加入的点小,后加的大

    每次加入直接模拟splay的插入。

    由于没有延迟标记,所以不需要pushdown,但要pushup

    每次pushup要维护两个值,当前节点结尾的最长上升子序列,当前子树的最长子序列

    推测可知,当前节点结尾的最长上升子序列只由左节点子树的序列的递推而来,因为左子树位置在前面,且小

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 using namespace std;
     6 const int MAXN=500010;
     7 int tot2,tot1,s[MAXN],pre[MAXN],ch[MAXN][2],key[MAXN];
     8 int size[MAXN],root,n,m,maxn[MAXN],g[MAXN];
     9 void NewNode(int &x,int fa,int k)
    10 {
    11     if (tot2) x=s[tot2--];
    12     else x=++tot1;
    13     key[x]=k;
    14     size[x]=1;
    15     pre[x]=fa;
    16     ch[x][0]=ch[x][1]=0;
    17 }
    18 void pushup(int x)
    19 {
    20     int lson=ch[x][0],rson=ch[x][1];
    21     size[x]=size[lson]+size[rson]+1;
    22     maxn[x]=max(max(g[x],maxn[rson]),maxn[lson]);
    23     if (key[x]==2e9||key[x]==0) maxn[x]=0,g[x]=0;
    24 }
    25 void rotate(int x,bool t)
    26 {
    27     int y=pre[x];
    28     ch[y][!t]=ch[x][t];
    29     pre[ch[x][t]]=y;
    30     if (pre[y])
    31         ch[pre[y]][ch[pre[y]][1]==y]=x;
    32     pre[x]=pre[y];
    33     ch[x][t]=y;
    34     pre[y]=x;
    35     pushup(y);pushup(x);
    36 }
    37 int getkth(int r,int k)
    38 {
    39     int x=size[ch[r][0]]+1;
    40     if (k==x) return r;
    41     if (k<x) getkth(ch[r][0],k);
    42     else getkth(ch[r][1],k-x);
    43 }
    44 void splay(int x,int goal)
    45 {
    46     while (pre[x]!=goal)
    47     {
    48         if (pre[pre[x]]==goal)
    49         {
    50             rotate(x,ch[pre[x]][0]==x);
    51         }
    52         else
    53         {
    54             int y=pre[x],kind=ch[pre[y]][0]==y;
    55             if (ch[y][kind]==x)
    56             {
    57                 rotate(x,!kind);
    58                 rotate(x,kind);
    59             }
    60             else
    61             {
    62                 rotate(y,kind);
    63                 rotate(x,kind);
    64             }
    65         }
    66     }
    67     pushup(x);
    68     if (goal==0) root=x;
    69 }
    70 int main()
    71 {int i,x;
    72     cin>>n;
    73     NewNode(root,0,2e9);
    74     NewNode(ch[root][1],root,0);
    75     for (i=1; i<=n; i++)
    76     {
    77         scanf("%d",&x);
    78         splay(getkth(root,x+1),0);
    79         splay(getkth(root,x+2),root);
    80         NewNode(ch[ch[root][1]][0],ch[root][1],i);
    81         splay(ch[ch[root][1]][0],0);
    82         g[root]=maxn[ch[root][0]]+1;
    83         pushup(root);
    84         printf("%d
    ",maxn[root]);
    85     }
    86 }
  • 相关阅读:
    【学习】018 Spring框架
    【学习】017 Mybatis框架
    【学习】016 MySQL数据库优化
    【学习】 015 Linux相关
    【学习】014 深入理解Http协议
    【学习】013 Servlet、Cookie、Session的简述
    js 异常判断
    CSS 文字概念小记
    Echarts tooltip 坐标值修改
    js 查找当前元素/this
  • 原文地址:https://www.cnblogs.com/Y-E-T-I/p/7207608.html
Copyright © 2011-2022 走看看