• 洛谷 P3391文艺平衡树 【fhq_treap】


    洛谷 P3391文艺平衡树

    题意见链接。。。

    题目明确说 splay模板题,我还是用了 fhq_treap(非旋treap)

    对于此题来说,操作分为这么几块:

    1、新加入节点,合并到基树中。

    (要记录 size,val,pio(优先级,rand一下))

    2、读入操作,开始翻转:

    因为翻转的是区间,所以我们先把树按 r 分成两部分,然后再把左子树按 l-1 分成两部分,对应的需要操作的区间就是右子树。

    用懒标记搞一下,再合并回去。

    3、分离与合并操作:

    分离:递归,如果 k 大于 size[left],那么就把左子树保留不变,递归右子树;左子树由 rt领头,右子树另到右子树中找节点。反之则同样。

    合并:按优先级比较,pri[x]<pri[y] 则 x 的左子树保留,用 x 的右子树去和 y 合并。反之则用 y 的左子树和 x 合并。

    4、上合与下传:

    由于懒标记,所以要 pushdown,本题因为区间翻转,只需要记录被翻转几次,两次等于没有,抵消。

    Pushup 也是线段树常规操作,更新完数据新的信息要上传到父亲节点更新。

    总的来说就这样吧,待填坑。

    贴代码:

     1 // 文艺平衡树 fhp_Treap
     2 // By YoungNeal
     3 #include<ctime>
     4 #include<cstdio>
     5 #include<cstdlib>
     6 #define N 100005
     7 
     8 int Root;
     9 int lazy[N];
    10 int n,m,cnt;
    11 int val[N],sze[N];
    12 int ch[N][2],prio[N];
    13 
    14 void pushup(int o){
    15     sze[o]=sze[ch[o][0]]+sze[ch[o][1]]+1;
    16 }
    17 
    18 void pushdown(int o){
    19     if(!lazy[o] or !o) return;
    20     ch[o][0]^=ch[o][1]^=ch[o][0]^=ch[o][1];
    21     lazy[ch[o][0]]^=1;
    22     lazy[ch[o][1]]^=1;
    23     lazy[o]=0;
    24 }
    25 
    26 void split(int o,int k,int &x,int &y){
    27     if(!o) x=y=0;
    28     else{
    29         pushdown(o);
    30         if(k>sze[ch[o][0]]) x=o,split(ch[o][1],k-sze[ch[o][0]]-1,ch[o][1],y);
    31         else y=o,split(ch[o][0],k,x,ch[o][0]);
    32         pushup(o);
    33     }
    34 }
    35 
    36 int merge(int x,int y){
    37     if(!x or !y) return x+y;
    38     pushdown(x); pushdown(y);
    39     if(prio[x]<prio[y]){
    40         ch[x][1]=merge(ch[x][1],y);
    41         pushup(x);
    42         return x;
    43     }
    44     else{
    45         ch[y][0]=merge(x,ch[y][0]);
    46         pushup(y);
    47         return y;
    48     }
    49 }
    50 
    51 int newnode(int v){
    52     val[++cnt]=v;
    53     sze[cnt]=1;
    54     prio[cnt]=rand();
    55     return cnt;
    56 }
    57 
    58 void res(int l,int r){
    59     int a,b,c,d;
    60     split(Root,r,a,b);
    61     split(a,l-1,c,d);
    62     lazy[d]^=1;
    63     Root=merge(merge(c,d),b);
    64 }
    65 
    66 void dfs(int now){
    67     if(!now) return;
    68     pushdown(now);
    69     dfs(ch[now][0]);
    70     printf("%d ",val[now]);
    71     dfs(ch[now][1]);
    72 }
    73 
    74 signed main(){
    75     srand(time(0));
    76     scanf("%d%d",&n,&m);
    77     for(int i=1;i<=n;i++)
    78         Root=merge(Root,newnode(i));
    79     //printf("Root=%d
    ",Root);
    80     for(int x,y,i=1;i<=m;i++){
    81         scanf("%d%d",&x,&y);
    82         res(x,y);
    83         //printf("i=%d
    ",i);
    84         //dfs(Root);
    85     }
    86     //printf("Root=%d
    ",Root);
    87     dfs(Root);
    88     return 0;
    89 }
    View Code

    fightin fighting fighting

  • 相关阅读:
    android intent 隐式意图和显示意图(activity跳转)
    Stack栈的三种含义
    gdi+ 高速绘制透明窗体
    Hibernate Criterion
    iOS安全攻防(三):使用Reveal分析他人app
    Android入门第八篇之GridView(九宫图)
    【Android动画】之Tween动画 (渐变、缩放、位移、旋转)
    Ubuntu下deb包的安装方法
    理解class.forName()
    Myeclipse7.5 下载 安装 注冊 注冊码 100%成功
  • 原文地址:https://www.cnblogs.com/Frank-King/p/9860642.html
Copyright © 2020-2023  润新知