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 }
以上是关于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