bzoj-2212 Tree Rotations
来源:互联网 发布:牛顿迭代法c语言编程 编辑:程序博客网 时间:2024/06/06 04:10
题意:
给出一个二叉树,叶子结点上有权值;
共有n个叶子结点,权值分别为1-n;
现可将所有结点的左右儿子交换,求最小的逆序对数;
2<=n<=200000;
题解:
这题读入有点鬼畜,但是写起来还是比较优雅的;
考虑到一个结点的子树具体形态与它是否和它的兄弟交换是无关的;
所以我们可以像分治一样,先计算子树之间的最小逆序对数;
然后将所有的权值扔到一个线段树中,向它的父亲传递;
它的父亲是没有权值的,我们只是在这里计算这两个线段树之间最小逆序对数,并将其合并就好了;
具体实现实际上只是一个合并操作中多了两个记录,考虑左子树与右子树是否交换;
对于一个线段树上的结点,我们累加:
左子树<=mid的结点数*右子树>mid的结点数作为左子树与右子树交换的逆序对数;
左子树>mid的结点数*右子树<=mid的结点数作为左子树与右子树不交换的逆序对数;
然后合并完成之后比较一下,累加到答案里就可以了;
答案可能超过int,时间复杂度O(nlogn)吧。。。
内存似乎比较玄学,应该是不超过nlogn的(空间复杂度不会大过时间复杂度呢);
代码:
#include<cctype>#include<stdio.h>#include<string.h>#include<algorithm>#define N 210000#define M 3000000#define LEN 1<<15#define lson l,mid,ls[no]#define rson mid+1,r,rs[no]using namespace std;typedef long long ll;int sum[M],ls[M],rs[M],tot;int st[M],top,n;ll ans;char getc(){static char *S,*T,buf[LEN];if(S==T){T=(S=buf)+fread(buf,1,LEN,stdin);if(S==T)return EOF;}return *S++;}int read(){static char ch;static int D;while(!isdigit(ch=getc()));for(D=ch-'0';isdigit(ch=getc());)D=D*10+ch-'0';return D;}int newnode(){if(top)return st[top--];return ++tot;}void delnode(int no){st[++top]=no;sum[no]=ls[no]=rs[no]=0;}void Pushup(int no){sum[no]=sum[ls[no]]+sum[rs[no]];}void Insert(int l,int r,int &no,int val){if(!no)no=newnode();if(l==r)sum[no]++;else{int mid=l+r>>1;if(val<=mid)Insert(lson,val);elseInsert(rson,val);Pushup(no);}}int merge(int l,int r,int nol,int nor,ll &cntl,ll &cntr){if(!nol||!nor)return nol+nor;cntl+=(ll)sum[rs[nol]]*sum[ls[nor]];cntr+=(ll)sum[ls[nol]]*sum[rs[nor]];int mid=l+r>>1,no=newnode();ls[no]=merge(l,mid,ls[nol],ls[nor],cntl,cntr);rs[no]=merge(mid+1,r,rs[nol],rs[nor],cntl,cntr);Pushup(no);delnode(nol),delnode(nor);return no;}int dfs(){int x;x=read();if(!x){int ls=dfs();int rs=dfs();if(sum[ls]>sum[rs])swap(ls,rs);ll cntl=0,cntr=0;int rt=merge(1,n,ls,rs,cntl,cntr);ans+=min(cntl,cntr);return rt;}else{int rt=0;Insert(1,n,rt,x);return rt;}}int main(){n=read();dfs();printf("%lld\n",ans);return 0;}
0 0
- bzoj-2212 Tree Rotations
- BZOJ 2212: [Poi2011]Tree Rotations
- bzoj 2212: [Poi2011]Tree Rotations
- BZOJ 2212([Poi2011]Tree Rotations-启发式合并)
- bzoj 2212: [Poi2011]Tree Rotations 线段树合并
- bzoj 2212: [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(线段树合并)
- 2212: [Poi2011]Tree Rotations
- BZOJ3702/2212 [Poi2011]Tree Rotations/二叉树
- 2212: [Poi2011]Tree Rotations/3702: 二叉树
- [BZOJ2212][Poi2011]Tree Rotations
- 【bzoj2212】 [Poi2011]Tree Rotations
- 【BZOJ】【P2212&P3702】【Poi2011】【Tree Rotations】【二叉树】【题解】【启发式合并】
- [Poi2011]Tree Rotations 解题报告
- 给自己做个地图故事 —— Trip to Greece
- 让职场新人得宠的七句话
- 条款55:让自己熟悉Boost
- Android面试题总结(一)
- 3D Touch 资料整理
- bzoj-2212 Tree Rotations
- ---------- 常用链接 ----------
- Win7使用jenkins一键打包unity工程的apk包
- 深入理解Win32结构化异常处理(二)
- CentOS 6.3安装JDK7
- 欢迎使用CSDN-markdown编辑器
- 【ISO】混合App中内嵌的浏览器,究竟是否需要单实例化?
- Android之Activity之间的数据通信方式大全(二)
- 怎样用MAC自带的抓图软件截图