题目链接

【BZOJ】
【洛谷】
【LOJ】

题解

由于是前序遍历,那么讨论一棵树上的逆序对的情况。

  • 两个节点都在左子树上
  • 两个节点都在右子树上
  • 两个节点分别在不同的子树上。

前两种情况其实也可以归结于第三种情况。

原因

因为两个节点不可能占据一个位置。
根据容斥原理,为了保证答案的正确性,我们递归求解不能计算两遍相同的答案。

回到正题
所以我们只需要讨论跨越两个子树的情况。
很显然,左子树中的所有点的\(dfs\)序都比右子树的子树中的小。
那么如果要交换,就是相反一下。
比较容易可以想到对于每一个节点都先建立一个权值线段树。
那么每一次的答案就从线段树的左子树和右子树中取最小值就可以了。

代码

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. namespace IOstream {
  4. #define gc getchar
  5. template <typename T>
  6. inline void read(T &x) {
  7. x = 0; T fl = 1; char c = 0;
  8. for (; c < '0' || c > '9'; c = gc())
  9. if (c == '-') fl = -1;
  10. for (; c >= '0' && c <= '9'; c = gc())
  11. x = (x << 1) + (x << 3) + (c ^ 48);
  12. x *= fl;
  13. }
  14. #undef gc
  15. } using namespace IOstream;
  16. typedef long long ll;
  17. const int N = 4000005 + 6;
  18. int n, cnt = 0, tot = 0;
  19. int rt[N];
  20. ll ans, f, g;
  21. struct node {
  22. int lc, rc, sz;
  23. } tr[N];
  24. int merge(int x, int y) {
  25. if (!x || !y) return x + y;
  26. f += 1ll * tr[tr[x].lc].sz * 1ll * tr[tr[y].rc].sz;
  27. g += 1ll * tr[tr[y].lc].sz * 1ll * tr[tr[x].rc].sz;
  28. tr[x].lc = merge(tr[x].lc, tr[y].lc);
  29. tr[x].rc = merge(tr[x].rc, tr[y].rc);
  30. tr[x].sz += tr[y].sz;
  31. return x;
  32. }
  33. void ins(int nod, int l, int r, int k) {
  34. tr[nod].sz ++;
  35. if (l == r) return;
  36. int mid = (l + r) >> 1;
  37. if (k <= mid) tr[nod].lc = ++ tot, ins(tr[nod].lc, l, mid, k);
  38. else tr[nod].rc = ++ tot, ins(tr[nod].rc, mid + 1, r, k);
  39. }
  40. #undef ls
  41. #undef rs
  42. int dfs() {
  43. int w; read(w);
  44. if (w) {
  45. rt[++ cnt] = ++ tot;
  46. ins(rt[cnt], 1, n, w);
  47. return rt[cnt];
  48. } else {
  49. int nod = merge(dfs(), dfs());
  50. ans += min(f, g);
  51. f = g = 0;
  52. return nod;
  53. }
  54. }
  55. int main() {
  56. read(n); ans = 0ll;
  57. dfs();
  58. printf("%lld\n", ans);
  59. return 0;
  60. }

「POI2011 R2 Day2」Tree Rotations【线段树合并】的更多相关文章

  1. LOJ 3066 - 「ROI 2016 Day2」快递(线段树合并+set 启发式合并)

    LOJ 题面传送门 人傻常数大,需要狠命卡--/wq/wq 画个图可以发现两条路径相交无非以下两种情况(其中红色部分为两路径的重叠部分,粉色.绿色的部分分别表示两条路径): 考虑如何计算它们的贡献,对 ...

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

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

  3. bzoj2212[Poi2011]Tree Rotations [线段树合并]

    题面 bzoj ans = 两子树ans + min(左子在前逆序对数, 右子在前逆序对数) 线段树合并 #include <cstdio> #include <cstdlib> ...

  4. BZOJ2212 [Poi2011]Tree Rotations 线段树合并 逆序对

    原文链接http://www.cnblogs.com/zhouzhendong/p/8079786.html 题目传送门 - BZOJ2212 题意概括 给一棵n(1≤n≤200000个叶子的二叉树, ...

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

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

  6. Bzoj P2212 [Poi2011]Tree Rotations | 线段树合并

    题目链接 通过观察与思考,我们可以发现,交换一个结点的两棵子树,只对这两棵子树内的节点的逆序对个数有影响,对这两棵子树以外的节点是没有影响的.嗯,然后呢?(っ•̀ω•́)っ 然后,我们就可以对于每一个 ...

  7. [bzoj2212]Tree Rotations(线段树合并)

    解题关键:线段树合并模板题.线段树合并的题目一般都是权值线段树,因为结构相同,求逆序对时,遍历权值线段树的过程就是遍历所有mid的过程,所有能求出所有逆序对. #include<iostream ...

  8. bzoj2212/3702 [Poi2011]Tree Rotations 线段树合并

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

  9. bzoj2212 Tree Rotations 线段树合并+动态开点

    题目传送门 思路: 区间合并线段树的题,第一次写,对于一颗子树,无论这个子树怎么交换,都不会对其他子树的逆序对造成影响,所以就直接算逆序对就好. 注意叶子节点是1到n的全排列,所以每个权值都只会出现1 ...

随机推荐

  1. 查询拼接SQL语句,多条件模糊查询

    多条件查询,使用StringBuilder拼接SQL语句,效果如下: 当点击按钮时代码如下: private void button1_Click(object sender, EventArgs e ...

  2. Java基础-异常、断言

    处理错误 如果Java程序运行期间出现了错误,并且由于出现错误导致某些操作没有完成,程序应该能够返回到一种安全状态,并能够让用户执行一些其他的命令:或者允许用户保存所有操作结果,并以妥善的方式终止程序 ...

  3. eclipse中集成maven

    一.环境 eclipse mar jdk 1.7 apache-maven-3.3.3 注意: 1> eclipse mar 已集成maven插件,我们只需要配置成自己的maven即可,类似ec ...

  4. Biorhythms(poj1006+中国剩余定理)

    Biorhythms Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 117973   Accepted: 37026 Des ...

  5. vue学习之ajax 简单快速使用axios

    vue2.x 推荐使用axios 1.首先使用安装 npm install axios -S 2.在哪用在哪引入 import axios from 'axios' 或则在main.js 中引入 在申 ...

  6. fab 菜单实现之前传-钟表表盘

    个人很喜欢谷歌的material design,很喜欢但是没有动手弄过,今天想动手操作一下Floating Action Button菜单,网上有很多种:圆形.扇形.射线.直线等.我想在一个例子中用到 ...

  7. 基于mapnik做切片服务器的几点总结

    文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/ 1.背景 在地图服务器的整体方案中,移动端采用矢量切片,样式解析采用th ...

  8. Android Studio错误日志-注解报错Annotation processors must be explicitly declared now.

    导入项目时,发现之前项目的butter knife报错,用到注解的应该都会报错Error:Execution failed for task ':app:javaPreCompileDebug'.&g ...

  9. PYTHON定义函数制作简单登录程序(详细)

    环境:python3.* 结构:   dict_name = {} #定义一个字典,后面用到 def newuser(): #定义注册函数 prompt1='login desired:' while ...

  10. 《Python 数据库 GUI CGI编程》

    本文地址:http://www.cnblogs.com/aiweixiao/p/8390417.html 原文地址 点击关注微信公众号 wenyuqinghuai 1.写在前边 上一次,我们介绍了Py ...