【bzoj3702】二叉树 权值线段树
来源:互联网 发布:电脑笔记软件 编辑:程序博客网 时间:2024/05/22 12:24
神奇的解法
对于每个节点,建出权值线段树
每次查询右子树的权值线段树和左子树的权值线段树,左子树中比右子树小的有多少?右子树比左子树小的有多少?(分别对应不交换的逆序对和交换的逆序对)
将左子树和右子树的权值线段树合并
递归进行这个操作
感觉复杂度很不靠谱,于是想证明一下复杂度
最开始权值线段树共O(nlogn)个节点,最后共O(n)个节点
每次合并两棵树的每个节点都要访问一遍,所以每个节点好像是要访问O(dep[i])次?
但是,合并两棵树后,有些重复的节点被合并到了一起
所以好像有些节点又没有合并O(dep[i])次?
对于每个节点,建出权值线段树
每次查询右子树的权值线段树和左子树的权值线段树,左子树中比右子树小的有多少?右子树比左子树小的有多少?(分别对应不交换的逆序对和交换的逆序对)
将左子树和右子树的权值线段树合并
递归进行这个操作
感觉复杂度很不靠谱,于是想证明一下复杂度
最开始权值线段树共O(nlogn)个节点,最后共O(n)个节点
每次合并两棵树的每个节点都要访问一遍,所以每个节点好像是要访问O(dep[i])次?
但是,合并两棵树后,有些重复的节点被合并到了一起
所以好像有些节点又没有合并O(dep[i])次?
感觉很靠谱,但是不会证明
#include<cstdio>#include<cstring>#include<cstdlib>#include<cmath>#include<iostream>#include<algorithm>#define maxn 400010#define N 4000100using namespace std;int lch[N],rch[N],sum[N];int root[maxn],l[maxn],r[maxn],w[maxn];int n,m,num,tot;long long ans,cnt1,cnt2;void dfs(int x){scanf("%d",&w[x]);if (!w[x]){l[x]=++num;dfs(num);r[x]=++num;dfs(num);}}void update(int x){sum[x]=sum[lch[x]]+sum[rch[x]];}void modify(int &x,int l,int r,int d){if (!x) x=++tot;if (l==r) {sum[x]=1;return;}int mid=(l+r)/2;if (d<=mid) modify(lch[x],l,mid,d);else modify(rch[x],mid+1,r,d);update(x);}int merge(int x,int y){if (!x) return y;if (!y) return x;cnt1+=(long long)sum[rch[y]]*sum[lch[x]];cnt2+=(long long)sum[rch[x]]*sum[lch[y]];lch[x]=merge(lch[x],lch[y]);rch[x]=merge(rch[x],rch[y]);update(x);return x;}void dfs1(int x){if (!w[x]){dfs1(l[x]);dfs1(r[x]);cnt1=cnt2=0;root[x]=merge(root[l[x]],root[r[x]]);ans+=min(cnt1,cnt2);}}int main(){scanf("%d",&n);num++;dfs(1);for (int i=1;i<=num;i++) if (w[i]) modify(root[i],1,n,w[i]);dfs1(1);printf("%lld\n",ans);return 0;}
0 0
- 【bzoj3702】二叉树 权值线段树
- 【bzoj3702】【二叉树】【线段树】
- bzoj3702二叉树 线段树合并
- [bzoj3702]二叉树
- bzoj3702 二叉树
- [bzoj3702]二叉树
- 【bzoj3702】二叉树
- [BZOJ3702][BZOJ2212]-线段树合并
- BZOJ3702/2212 [Poi2011]Tree Rotations/二叉树
- HDU1754 线段树 (完全二叉树)
- hdoj 2795 Billboard 【线段树】&&【二叉树】
- 线段树(完全二叉树)
- bzoj 3702: 二叉树 (线段树)
- bzoj 3702: 二叉树 线段树合并
- 平衡二叉树SBT||线段树区间维护poj2892
- hdoj 1754 I Hate It【线段树&&二叉树】【线段树求最值】
- BZOJ 3685 zkw线段树 || 权值线段树
- 模板 权值线段树
- 开源jar包
- 198. House Robber
- 算法#05--神作:深入浅出傅里叶变换
- MapGIS6.7_学习中遇到的问题(5):用户点文件(.txt)转MapGIS线文件(.WL)
- android:scheme 通过uri跳转到APP应用指定Activity
- 【bzoj3702】二叉树 权值线段树
- 使用Python对文件名进行排序
- C++ TR1 智能指针shared_ptr的使用(转)
- ecshop二次开发--左侧导航
- 使用spring进行属性注入的实例解析(spring面向切面和控制反转)。
- 从Google学到的厕所文化
- 回车和换行
- Android 日期工具类DateUtil
- [Android]Broadcast,Intent,PendingIntent,Handler例子