2212: [Poi2011]Tree Rotations

https://www.lydsy.com/JudgeOnline/problem.php?id=2212

分析:

  线段树合并。

  首先对每个节点建立一棵权值线段树,然后遍历整棵树,从叶子节点开始合并,每次合并两个节点的主席树,判断是否交换这两个节点,求出这两个节点分在前面所形成的逆序对。

  求逆序对:对于主席树中的右子树一定比左子树大,所以每次合并一个节点时,直接用右子树的个数乘以左子树的个数,不断递归。

代码:

  1. #include<cstdio>
  2. #include<algorithm>
  3. #include<cstring>
  4. #include<cmath>
  5. #include<iostream>
  6. #include<cctype>
  7. #include<set>
  8. #include<vector>
  9. #include<queue>
  10. #include<map>
  11. #define fi(s) freopen(s,"r",stdin);
  12. #define fo(s) freopen(s,"w",stdout);
  13. using namespace std;
  14. typedef long long LL;
  15.  
  16. inline int read() {
  17. int x=,f=;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-;
  18. for(;isdigit(ch);ch=getchar())x=x*+ch-'';return x*f;
  19. }
  20.  
  21. const int N = ;
  22.  
  23. int A[N << ], T[N << ][], Root[N << ], sum[N * ], ls[N * ], rs[N * ];
  24. int Index, tot, Rt;
  25. LL Ans, Ans0, Ans1;
  26.  
  27. void ReadTree(int &x) {
  28. x = ++Index;
  29. A[x] = read();
  30. if (A[x]) return ;
  31. ReadTree(T[x][]);
  32. ReadTree(T[x][]);
  33. }
  34.  
  35. void Insert(int l,int r,int &rt,int p) {
  36. rt = ++tot;
  37. sum[rt] = ;
  38. if (l == r) return ;
  39. int mid = (l + r) >> ;
  40. if (p <= mid) Insert(l, mid, ls[rt], p);
  41. else Insert(mid + , r, rs[rt], p);
  42. }
  43.  
  44. int Merge(int x,int y) { // 合并x y
  45. if (!x || !y) return x + y;
  46. Ans0 += 1ll * sum[rs[x]] * sum[ls[y]]; // x在前
  47. Ans1 += 1ll * sum[rs[y]] * sum[ls[x]]; // y在前
  48. ls[x] = Merge(ls[x], ls[y]);
  49. rs[x] = Merge(rs[x], rs[y]);
  50. sum[x] += sum[y];
  51. return x;
  52. }
  53.  
  54. void solve(int x) {
  55. if (A[x]) return ;
  56. solve(T[x][]); solve(T[x][]);
  57. Ans0 = , Ans1 = ;
  58. Root[x] = Merge(Root[T[x][]], Root[T[x][]]);
  59. Ans += min(Ans0, Ans1);
  60. }
  61.  
  62. int main() {
  63.  
  64. int n = read();
  65. ReadTree(Rt);
  66. for (int i=; i<=Index; ++i)
  67. if (A[i]) Insert(, n, Root[i], A[i]);
  68. solve(Rt);
  69. cout << Ans << endl;
  70. return ;
  71. }

2212: [Poi2011]Tree Rotations的更多相关文章

  1. BZOJ 2212: [Poi2011]Tree Rotations( 线段树 )

    线段树的合并..对于一个点x, 我们只需考虑是否需要交换左右儿子, 递归处理左右儿子. #include<bits/stdc++.h> using namespace std; #defi ...

  2. [BZOJ 2212] [Poi2011] Tree Rotations 【线段树合并】

    题目链接:BZOJ - 2212 题目分析 子树 x 内的逆序对个数为 :x 左子树内的逆序对个数 + x 右子树内的逆序对个数 + 跨越 x 左子树与右子树的逆序对. 左右子树内部的逆序对与是否交换 ...

  3. bzoj 2212: [Poi2011]Tree Rotations

    Description Byteasar the gardener is growing a rare tree called Rotatus Informatikus. It has some in ...

  4. BZOJ 2212 [Poi2011]Tree Rotations(线段树合并)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2212 [题目大意] 给出一棵二叉树,每个叶节点上有一个权值,现在可以任意交换左右儿子, ...

  5. bzoj 2212 : [Poi2011]Tree Rotations (线段树合并)

    题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=2212 思路:用线段树合并求出交换左右儿子之前之后逆序对的数量,如果数量变小则交换. 实现 ...

  6. 【BZOJ】2212: [Poi2011]Tree Rotations

    题意 给一棵\(n(1 \le n \le 200000)\)个叶子的二叉树,可以交换每个点的左右子树,要求前序遍历叶子的逆序对最少. 分析 可以发现如果交换非叶结点的左右子树,对子树内的交换无影响, ...

  7. BZOJ.2212.[POI2011]Tree Rotations(线段树合并)

    题目链接 \(Description\) 给定一棵n个叶子的二叉树,每个叶节点有权值(1<=ai<=n).可以任意的交换两棵子树.问最后顺序遍历树得到的叶子权值序列中,最少的逆序对数是多少 ...

  8. BZOJ2212: [Poi2011]Tree Rotations

    2212: [Poi2011]Tree Rotations Time Limit: 20 Sec  Memory Limit: 259 MBSubmit: 391  Solved: 127[Submi ...

  9. 【BZOJ2212】[Poi2011]Tree Rotations 线段树合并

    [BZOJ2212][Poi2011]Tree Rotations Description Byteasar the gardener is growing a rare tree called Ro ...

随机推荐

  1. Kill占用指定端口的进程的方法

    (1)查询占用指定端口进程的PID 打开cmd命令行,输入netstat -ano|findstr 8080(指定端口号) 最后一列即为占用该端口的进程的PID (2)KILL指定PID的进程 紧接着 ...

  2. Intellij IDEA 修改编辑器背景颜色

    对眼睛有益的RGB数值分别是(199,237,204)

  3. Yii 集成 PHPExcel读取Excel文件

    PHPexcel官方下载以后,放入Yii的protected\extensions\phpexcel下面 try { spl_autoload_unregister(array('YiiBase', ...

  4. UVa 580 - Critical Mass(递推)

    链接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...

  5. UVa 10003 - Cutting Sticks(区间DP)

    链接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...

  6. vue - 数据驱动,组件化, 双向绑定原理

    1.数据驱动 传统的前端数据交互是用Ajax从服务端获取数据,然后操作DOM来改变视图: Vue.js 是一个提供了 MVVM 风格的双向数据绑定的 Javascript 库,专注于View 层.它让 ...

  7. Softmax回归(Softmax Regression, K分类问题)

    Softmax回归:K分类问题, 2分类的logistic回归的推广.其概率表示为: 对于一般训练集:                     系统参数为:      Softmax回归与Logist ...

  8. 配置文件和mybatis文件存放位置导致系统启动不了

    1.web.xml <!-- 加载spring容器 --> <context-param> <param-name>contextConfigLocation< ...

  9. 【nlogn LIS】 模板

    总结:stl真好用 #include <cstdio> #include <cstring> #include <iostream> #include <al ...

  10. 【数据结构】浅谈倍增求LCA

    思路 运用树上倍增法可以高效率地求出两点x,y的公共祖先LCA 我们设f[x][k]表示x的2k辈祖先 f[x][0]为x的父节点 因为从x向根节点走2k 可以看成从x走2k-1步 再走2k-1步 所 ...