zoukankan      html  css  js  c++  java
  • BZOJ2212 [POI2011] Tree Rotations 【treap】

    题目分析:

    写的无旋treap应该跑不过,但bzoj判断的总时限。把相关实现改成线段树合并就可以了。

    代码:

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 
      4 const int maxn = 1000020;
      5 
      6 int n;
      7 int ch[maxn][2],num,val[maxn];
      8 
      9 int son[maxn>>2][2],sz[maxn],rot[maxn],data[maxn],key[maxn];
     10 
     11 long long ans = 0;
     12 
     13 int merge(int r1,int r2){
     14     if(r1 == 0) return r2; if(r2 == 0) return r1;
     15     if(key[r1] < key[r2]){
     16     son[r1][1] = merge(son[r1][1],r2);
     17     sz[r1] = sz[son[r1][0]]+sz[son[r1][1]]+1;
     18     return r1;
     19     }else{
     20     son[r2][0] = merge(r1,son[r2][0]);
     21     sz[r2] = sz[son[r2][0]]+sz[son[r2][1]]+1;
     22     return r2;
     23     }
     24 }
     25 pair<int,int> split(int rt,int k){
     26     if(k == 0) return make_pair(0,rt);
     27     if(k >= sz[rt]) return make_pair(rt,0); 
     28     if(sz[son[rt][0]] >= k){
     29     pair<int,int> res = split(son[rt][0],k);
     30     son[rt][0] = res.second; res.second = rt;
     31     sz[rt] = sz[son[rt][0]] + sz[son[rt][1]] + 1;
     32     return res;
     33     }else{
     34     pair<int,int> res = split(son[rt][1],k-sz[son[rt][0]]-1);
     35     son[rt][1] = res.first; res.first = rt;
     36     sz[rt] = sz[son[rt][0]] + sz[son[rt][1]] + 1;
     37     return res;
     38     }
     39 }
     40 int found(int now,int x){
     41     if(now == 0) return 0;
     42     if(data[now] == x) return sz[son[now][0]];
     43     if(data[now] < x) return sz[son[now][0]]+1+found(son[now][1],x);
     44     else return found(son[now][0],x);
     45 }
     46 
     47 void dfs(int now){
     48     int d; scanf("%d",&d);
     49     if(d){val[now] = d; return;}
     50     ch[now][0] = ++num; dfs(num); ch[now][1] = ++num; dfs(num);
     51 }
     52 
     53 long long alpha,beta;
     54 void walk(int A,int B){
     55     int z = found(B,data[A]); alpha += z; beta += (sz[B]-z);
     56     if(son[A][0]) walk(son[A][0],B);
     57     if(son[A][1]) walk(son[A][1],B);
     58 }
     59 
     60 void dfs2(int A,int &B){
     61     if(son[A][0]) dfs2(son[A][0],B),son[A][0] = 0;
     62     if(son[A][1]) dfs2(son[A][1],B),son[A][1] = 0;
     63     sz[A] = 1; int z = found(B,data[A]);
     64     pair<int,int> pr = split(B,z);
     65     B = merge(merge(pr.first,A),pr.second);
     66 }
     67 
     68 void dfs1(int now){
     69     if(val[now]){
     70     num++;
     71     key[num]=rand();
     72     sz[num]=1;
     73     data[num]=val[now];
     74     rot[now]=num;
     75     return;
     76     }
     77     dfs1(ch[now][0]); dfs1(ch[now][1]);
     78     alpha = 0,beta = 0;
     79     if(sz[rot[ch[now][0]]] < sz[rot[ch[now][1]]]){
     80     walk(rot[ch[now][0]],rot[ch[now][1]]);
     81     dfs2(rot[ch[now][0]],rot[ch[now][1]]);
     82     rot[now] = rot[ch[now][1]];
     83     }else {
     84     walk(rot[ch[now][1]],rot[ch[now][0]]);
     85     dfs2(rot[ch[now][1]],rot[ch[now][0]]);
     86     rot[now] = rot[ch[now][0]];
     87     }
     88     ans += min(alpha,beta);
     89 }
     90 
     91 void read(){
     92     scanf("%d",&n);
     93     num = 1;
     94     dfs(1);
     95 }
     96 
     97 void work(){
     98     num = 0;
     99     dfs1(1);
    100     printf("%lld",ans);
    101 }
    102 
    103 int main(){
    104     read();
    105     work();
    106     return 0;
    107 }
  • 相关阅读:
    数据结构与算法-字符串与字符串匹配算法
    操作系统-PV操作的原理和几种常见问题
    操作系统-进程(8)-临界区管理
    利用队列实现逐行打印杨辉三角形的前n行
    操作系统-进程(7)死锁和银行家算法
    计算机网络-网络层(6)ICMP协议
    操作系统-进程(6)管程
    计算机网络-链路层(5)点对点链路控制
    操作系统-进程(5)进程通信机制
    RTSP/RTMP流媒体协议网页无插件直播视频平台浏览器请求地址自带尾缀符解释说明
  • 原文地址:https://www.cnblogs.com/Menhera/p/9563912.html
Copyright © 2011-2022 走看看