BZOJTree Rotations(线段树的合并)
来源:互联网 发布:滴滴面试经验 java 编辑:程序博客网 时间:2024/06/03 19:25
题目链接2212:[Poi2011]Tree Rotations
题意:
给定一颗完全二叉树,每个叶子节点有一个权值,你可以任意交换每个点的左右儿子,使得最后整棵树中序遍历的逆序对个数最少
搬运题解系列:
考虑一个节点的左右子树的子树是否交换过对这个节点的逆序对数目没有影响,只有这个节点直接的子树交换才会产生影响
那么我们可以分治的去计算每个节点的贡献,然后向上传递
每个节点的逆序对是左子树的逆序对的数量+右子树的逆序对数量+跨越子树的逆序对数量
我们交换子树更改的就是最后那个跨越子树的逆序对数量,那么:
如果我们交换了左右子树,跨越子树的逆序对数量为没交换时左子树中<mid的数的数量*右子树中>=mid的数的数量
如果我们没有交换左右子树,那么逆序对数量就是左子树中>=mid的数的数量*右子树中<mid的数的数量
然后我们向上传递信息。这一步用线段树合并即可。
PS:第一道线段树合并,需要好好理解!
#include<bits/stdc++.h>using namespace std;#define LL long long#define N 400005#define MaxNode 4000005int n, rt, Index, IndexT;int a[MaxNode], root[MaxNode], ls[MaxNode], rs[MaxNode], Tree[MaxNode], son[MaxNode][2];//root以每个节点建立的权值线段树的根//ls树的左儿子,rs树的右儿子//Tree所有节点的权值线段树//son以i号节点建立的权值线段树的编号,合并后就为i号节点及其子节点的权值线段树的节点编号LL ans1, ans2, ans;void Read_Tree(int &x){ x=++IndexT; scanf("%d", &a[x]); if(a[x]!=0) return ; Read_Tree(ls[x]); Read_Tree(rs[x]);}void push_up(int x){ Tree[x]=Tree[son[x][0]]+Tree[son[x][1]];}void Insert(int &x, int l, int r, int pos){ if(x==0) x=++Index; if(l==r) { Tree[x]=1; return ; } int mid=(l+r)>>1; if(pos<=mid) Insert(son[x][0], l, mid, pos); else Insert(son[x][1], mid+1, r, pos); push_up(x);}int Merge(int x, int y){ if(!x) return y; if(!y) return x; ans1+=(LL)Tree[son[x][1]]*(LL)Tree[son[y][0]]; ans2+=(LL)Tree[son[x][0]]*(LL)Tree[son[y][1]]; son[x][0]=Merge(son[x][0], son[y][0]); son[x][1]=Merge(son[x][1], son[y][1]); push_up(x); return x;}void solve(int x){ if(a[x]) return ; solve(ls[x]);solve(rs[x]); ans1=ans2=0; root[x]=Merge(root[ls[x]], root[rs[x]]); ans += min(ans1, ans2);}int main(){ scanf("%d", &n); Read_Tree(rt); for(int i=1; i<=IndexT; i++) if(a[i]!=0) Insert(root[i], 1, n, a[i]); solve(rt); cout<<ans<<endl; return 0;}
阅读全文
0 0
- BZOJTree Rotations(线段树的合并)
- Bzoj2212:[Poi2011]Tree Rotations:线段树的合并
- 【POI2011】Tree Rotations(线段树合并)
- bzoj 2212: [Poi2011]Tree Rotations 线段树合并
- [BZOJ2212][Poi2011]Tree Rotations(线段树合并)
- BZOJ 2212 & POI 18 Tree Rotations(线段树合并)
- bzoj 2212 [Poi2011]Tree Rotations(线段树合并)
- BZOJ 2212: [Poi2011]Tree Rotations 线段树合并
- BZOJ 2212 [Poi2011]Tree Rotations 线段树合并
- 【bzoj 2212】Tree Rotations(线段树合并)
- 【bzoj2212】[Poi2011]Tree Rotations(线段树的合并)(主席树-可持久化线段树)
- bzoj2212&3702 [Poi2011]Tree Rotations 二叉树 (线段树合并)
- 线段树的合并
- bzoj 2212: [Poi2011]Tree Rotations (线段树)
- 【BZOJ】【P2212&P3702】【Poi2011】【Tree Rotations】【二叉树】【题解】【启发式合并】
- BZOJ 2212([Poi2011]Tree Rotations-启发式合并)
- BZOJ 2212线段树的合并
- [BZOJ3307][线段树合并]雨天的尾巴
- jeesite使用数据库oracle12c
- 深入理解 Python 异步编程
- HotSpot C2编译器
- linux 下面SCP拷贝文件
- BZOJ 3932 CQOI2015 主席树
- BZOJTree Rotations(线段树的合并)
- WIN7 64 位旗舰版安装 CUDA 6.0 过程(显卡为NVIDIA GT 440)
- 437. Path Sum III
- mysql深入二
- 关于监控系统的一些想法心得
- java泛型使用
- java面试-判断+代码查错
- 006-SLF4J的简单使用
- UVA 839