BZOJ 2212 [Poi 2011] 线段树合并 解题报告
来源:互联网 发布:少女漫画软件下载 编辑:程序博客网 时间:2024/06/05 09:56
2212: [Poi2011]Tree Rotations
Description
现在有一棵二叉树,所有非叶子节点都有两个孩子。在每个叶子节点上有一个权值(有n个叶子节点,满足这些权值为1..n的一个排列)。可以任意交换每个非叶子节点的左右孩子。
要求进行一系列交换,使得最终所有叶子节点的权值按照遍历序写出来,逆序对个数最少。
Input
第一行n
下面每行,一个数x
如果x==0,表示这个节点非叶子节点,递归地向下读入其左孩子和右孩子的信息,
如果x!=0,表示这个节点是叶子节点,权值为x
1<=n<=200000
Output
一行,最少逆序对个数
Sample Input
3
0
0
3
1
2
Sample Output
1
【解题报告】
首先我们要知道,一个节点的左右子树的子树是否交换过对这个节点的逆序对数目没有影响
每个节点的逆序对是 左子树的逆序对的数量+右子树的逆序对数量+跨越子树的逆序对数量
交换子树更改的只是最后那个跨越子树的逆序对数量。
如果我们交换了左右子树,跨越子树的逆序对数量为没交换时左子树中
/************************************************************** Problem: 2212 User: onepointo Language: C++ Result: Accepted Time:10536 ms Memory:224276 kb****************************************************************/#include<cstdio>#include<cstring>#include<algorithm>using namespace std;#define N 8000010#define LL long longLL ans=0,ans1=0,ans2=0; int n,r[N],root,ls[N],rs[N];int a[N],s[N][2],ind=0,t[N];void build(int &rt){ rt=++ind;scanf("%d",&a[rt]); if(a[rt]) return; build(ls[rt]); build(rs[rt]);}void pushup(int rt){ t[rt]=t[s[rt][0]]+t[s[rt][1]];}void insert(int &rt,int l,int r,int pos){ if(!rt) rt=++ind; if(l==r) {t[rt]=1;return;} int m=(l+r)>>1; if(pos<=m) insert(s[rt][0],l,m,pos); else insert(s[rt][1],m+1,r,pos); pushup(rt); }int merge(int x,int y){ if(!x) return y; if(!y) return x; ans1+=(LL)t[s[x][1]]*t[s[y][0]]; ans2+=(LL)t[s[x][0]]*t[s[y][1]]; s[x][0]=merge(s[x][0],s[y][0]); s[x][1]=merge(s[x][1],s[y][1]); pushup(x);return x; }void solve(int x){ if(a[x]) return; solve(ls[x]);solve(rs[x]); ans1=ans2=0; r[x]=merge(r[ls[x]],r[rs[x]]); ans+=min(ans1,ans2); } int main(){ scanf("%d",&n); build(root); for(int i=1;i<=ind;++i) { if(a[i]) insert(r[i],1,n,a[i]); } solve(root); printf("%lld\n",ans); return 0;}
阅读全文
0 0
- BZOJ 2212 [Poi 2011] 线段树合并 解题报告
- BZOJ 2733 [HNOI 2012] 线段树合并 解题报告
- BZOJ 2212 & POI 18 Tree Rotations(线段树合并)
- BZOJ 1012 线段树 解题报告
- BZOJ 2527 [Poi 2011] 整体二分 解题报告
- BZOJ 4726 [POI 2017] 树DP 解题报告
- BZOJ 2079 [Poi 2010] 图论 解题报告
- BZOJ 1131 [POI 2008] 解题报告
- 线段树 划分树 合并树 解题报告
- BZOJ 1067 [SCOI 2007] 线段树 解题报告
- bzoj 4552 排序 线段树+二分 解题报告
- bzoj 4565 字符合并 DP 解题报告
- BZOJ 2212线段树的合并
- BZOJ 2212 线段树启发式合并
- bzoj 2212(线段树合并)
- BZOJ 3833 [POI 2014] Solar Lamps 解题报告
- BZOJ 2792 [POI 2012] 二分答案 解题报告
- BZOJ 1116 [POI 2008] 并查集 解题报告
- 浅析三种特殊进程:孤儿进程,僵尸进程和守护进程
- 静态变量、全局变量和局部变量
- 学习笔记之面向对象编程28(GUI编程之Panel)
- 商业银行的表内业务与表外业务
- Java中使用PB教程
- BZOJ 2212 [Poi 2011] 线段树合并 解题报告
- tittle标题图标
- [spring学习] 之 spring-boot 默认配置
- Spring Boot -- Spring Data Jpa(6)
- android 拨打电话
- Tomcat 源码阅读(七)Tomcat加载web项目
- MAC下更新自带的PHP版本到5.6或7.0
- 渗透日记5:某站登入框存在post注入
- Maven依赖分析