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

    优秀的性质:从 (1)(n) 依次插入,所以我们每次只用在比当前位置靠前的所有 (f[i]) 中取个 (max) 然后 (+1) ;我们可以用 平衡树 模拟这个过程。

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #define R register int
    using namespace std;
    namespace Luitaryi {
    inline int g() { R x=0,f=1;
      register char s; while(!isdigit(s=getchar())) f=s=='-'?-1:f;
      do x=x*10+(s^48); while(isdigit(s=getchar())); return x*f;
    } const int N=100010;
    int n,tot,rt;
    int ch[N][2],sz[N],vl[N],pos[N],f[N],dat[N];
    #define ls(x) (ch[x][0])
    #define rs(x) (ch[x][1])
    inline int cre(int v,int p) {
      R tr=++tot;
      dat[tr]=rand(),sz[tr]=1,vl[tr]=f[pos[tr]=p]=v;
      return tr;
    }
    inline void upd(int tr) {
      sz[tr]=sz[ls(tr)]+sz[rs(tr)]+1;
      vl[tr]=max(f[pos[tr]],max(vl[ls(tr)],vl[rs(tr)]));
    }
    inline void split(int tr,int& x,int& y,int k) {
      if(!tr) return x=y=0,void();
      if(sz[ls(tr)]<k) x=tr,split(rs(tr),rs(x),y,k-sz[ls(tr)]-1);
      else y=tr,split(ls(tr),x,ls(y),k);
      upd(tr);
    }
    inline int merge(int x,int y) {
      if(!x||!y) return x+y;
      if(dat[x]<dat[y]) {
        rs(x)=merge(rs(x),y),upd(x);
        return x;
      } ls(y)=merge(x,ls(y)),upd(y);
      return y;
    }
    inline void main() {
      n=g(); srand(20040109);
      for(R i=1,v,x,y,z;i<=n;++i) {
        v=g();
        split(rt,x,y,v),
        z=cre(vl[x]+1,i);
        x=merge(x,z);
        rt=merge(x,y);
        printf("%d
    ",vl[rt]);
      }
    }
    } signed main() {Luitaryi::main(); return 0;}
    

    2020.01.19

  • 相关阅读:
    Winefish-GTK LaTeX 编辑器
    GPuTTY:SSH 会话治理器
    Zudeo──高清版 Youtube
    HardInfo-体系信息搜集对象
    Liferea 1.2.0 正式版
    HomeBank:家庭理财软件
    ParolaPass:暗码天生器
    VLC Media Player 0.8.6
    流程图的绘制方法
    Delphi 2009 中的匿名方法(reference to)
  • 原文地址:https://www.cnblogs.com/Jackpei/p/12212583.html
Copyright © 2011-2022 走看看