• 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 }
  • 相关阅读:
    HTTP响应状态码
    跨域
    第一章-极限与函数
    离群点检测
    关联规则(初识)
    python分类预测模型的特点
    分类预测算法评价(初识)
    人工神经网络(初识)
    决策树(初识)
    挖掘建模
  • 原文地址:https://www.cnblogs.com/Menhera/p/9563912.html
Copyright © 2020-2023  润新知