P3521 [POI2011]ROT-Tree Rotations

Posted wyher

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P3521 [POI2011]ROT-Tree Rotations相关的知识,希望对你有一定的参考价值。

P3521 [POI2011]ROT-Tree Rotations

  本题可以通过合并数据结构解决。

  权值线段树合并的时间复杂度为O(nlogn)。

证明:

   • n个节点相互独立。

   • 考虑合并节点的意义:两棵线段树在当前区间内都有值且新的树在当前区间的值相对原来两棵树的值都增加了。

   • 说明对于一个线段树区间,merge时访问到它的次数不会超过该区间的长度大小次。

   • 那么显然总访问次数的上限为 nlogn。

 

技术图片
 1 #include<bits/stdc++.h>
 2 #define ll long long
 3 using namespace std;
 4 int n,root,now,cnt;
 5 ll a,b,ans;
 6 int sum[4000050];
 7 int son[4000050][2];
 8 void calc_add(int &u,int l,int r)
 9 {
10     u=++cnt;    ++sum[u];
11     if(l==r)    return ;
12     int mid=(l+r)>>1;
13     if(now<=mid)    calc_add(son[u][0],l,mid);
14     else            calc_add(son[u][1],mid+1,r);
15 }
16 void merge(int &u,int v)
17 {
18     if(!u||!v)
19     {
20         u=u|v;
21         return ;
22     }
23     sum[u]+=sum[v];
24     a+=(ll)sum[son[u][0]]*sum[son[v][1]];
25     b+=(ll)sum[son[u][1]]*sum[son[v][0]];
26     merge(son[u][0],son[v][0]);
27     merge(son[u][1],son[v][1]);
28 }
29 void dfs(int &u)
30 {
31     scanf("%d",&now);
32     int ls,rs;
33     if(!now)
34     {
35         dfs(ls=0);    dfs(rs=0);
36         a=b=0;    u=ls;
37         merge(u,rs);
38         ans+=min(a,b);
39     }
40     else
41         calc_add(u,1,n);
42 }
43 int main()
44 {
45     scanf("%d",&n);
46     dfs(root);
47     printf("%lld",ans);
48     return 0;
49 }
View Code

 

以上是关于P3521 [POI2011]ROT-Tree Rotations的主要内容,如果未能解决你的问题,请参考以下文章

Luogu P3521 [POI2011]ROT-Tree Rotations

题解 P3521 [POI2011]ROT-Tree Rotations

「Luogu P3521 [POI2011]ROT-Tree Rotations」

LuoguP3521 [POI2011]ROT-Tree Rotations

bzoj 2212[POI2011]ROT-Tree Rotations - 线段树合并

[POI2011]ROT-Tree Rotations