$des$

现在有一棵二叉树,所有非叶子节点都有两个孩子。在每个叶子节点上有一个权值(有n个叶子节点,满足这些权值为1..n的一个排列)。可以任意交换每个非叶子节点的左右孩子。
要求进行一系列交换,使得最终所有叶子节点的权值按照中序遍历写出来,逆序对个数最少。

$sol$

可以发现每次交换对子树内的逆序对数没有影响。所以我们可以使每棵子树都最优。

对每个叶子节点维护一棵权值线段树,自底向上更新.

更新的时候枚举是否需要交换,然后把两棵线段树合并即可.

注意动态开点.

#include<bits/stdc++.h>

#define ll long long

using namespace std;

#define Rep(i, a, b) for(int i = a; i <= b; i ++)

#define gc getchar()
inline int read() {
int x = , f = ;
char c = gc;
while(c < '' || c > '') {
if(c == '-') f = -;
c = gc;
}
while(c >= '' && c <= '') x = x * + c - '', c = gc;
return x * f;
} int n, sz, seg;
ll ans, cnt1, cnt2;
int v[], l[], r[], root[];
int sum[], ls[], rs[]; namespace $ {
void readtree(int x) {
v[x] = read();
if(!v[x]) {
l[x] = ++ sz;
readtree(l[x]);
r[x] = ++ sz;
readtree(r[x]);
}
} void pushup(int k) {
sum[k] = sum[ls[k]] + sum[rs[k]];
} void build(int &k, int l, int r, int val) {
if(!k) k = ++ seg;
if(l == r) {
sum[k] = ;
return;
}
int mid = (l + r) >> ;
if(val <= mid) build(ls[k], l, mid, val);
else build(rs[k], mid + , r, val);
pushup(k);
} int merge(int x,int y) {
if(!x) return y;
if(!y) return x;
cnt1 += (ll)sum[rs[x]] * sum[ls[y]];
cnt2 += (ll)sum[ls[x]] * sum[rs[y]];
ls[x] = merge(ls[x], ls[y]);
rs[x] = merge(rs[x], rs[y]);
pushup(x);
return x;
} void solve(int x) {
if(!x) return;
solve(l[x]);
solve(r[x]);
if(!v[x]) {
cnt1 = cnt2 = ;
root[x] = merge(root[l[x]], root[r[x]]);
ans += min(cnt1,cnt2);
}
}
} int main() {
n = read();
++ sz;
$:: readtree();
Rep(i, , sz)
if(v[i]) $:: build(root[i], , n, v[i]);
$:: solve();
cout << ans;
return ;
}

80: bzoj3705 线段树合并的更多相关文章

  1. 【BZOJ-3681】Arietta 网络流 + 线段树合并

    3681: Arietta Time Limit: 20 Sec  Memory Limit: 64 MBSubmit: 182  Solved: 70[Submit][Status][Discuss ...

  2. P4556 雨天的尾巴 线段树合并

    使用线段树合并,每个节点维护一棵权值线段树,下标为救济粮种类,区间维护数量最多的救济粮编号(下标).所以每个节点答案即为\(tre[rot[x]]\). 然后运用树上点的差分思想,对于分发路径\(u, ...

  3. HDU-6704 K-th occurrence (后缀自动机father树上倍增建权值线段树合并)

    layout: post title: HDU-6704 K-th occurrence (后缀自动机father树上倍增建权值线段树合并) author: "luowentaoaa&quo ...

  4. CF600E Lomsat gelral (线段树合并)

    相当于是线段树合并的模板题,比(雨天的尾巴)还要板. 唯一注意的是线段树的更新,因为同一子树中可能有多种颜色占主导地位,要输出编号和,比如一颗子树中,1出现3次(最多),3出现3次,那么应该输出4. ...

  5. P4556 [Vani有约会]雨天的尾巴 /【模板】线段树合并 (树上差分+线段树合并)

    显然的树上差分问题,最后要我们求每个点数量最多的物品,考虑对每个点建议线段树,查询子树时将线段树合并可以得到答案. 用动态开点的方式建立线段树,注意离散化. 1 #include<bits/st ...

  6. [XJOI NOI2015模拟题13] C 白黑树 【线段树合并】

    题目链接:XJOI - NOI2015-13 - C 题目分析 使用神奇的线段树合并在 O(nlogn) 的时间复杂度内解决这道题目. 对树上的每个点都建立一棵线段树,key是时间(即第几次操作),动 ...

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

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

  8. BZOJ 3307: 雨天的尾巴( LCA + 线段树合并 )

    路径(x, y) +z : u处+z, v处+z, lca(u,v)处-z, fa(lca)处-z, 然后dfs一遍, 用线段树合并. O(M log M + M log N). 复杂度看起来不高, ...

  9. BZOJ2733 [HNOI2012]永无乡 【线段树合并】

    本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ...

随机推荐

  1. 【模板】bitset

    Bitset常用操作: bitset<size> s; //定义一个大小为size的bitset s.count(); //统计s中1的个数 s.set(); //将s的所有位变成1 s. ...

  2. Windows 2003 服务器 关闭IIS中FTP匿名访问

    控制面板 –> 管理工具 –> Internet信息服务管理器打开后左侧选择相应的FTP站点右击 –> 属性 –> 安全帐户允许匿名连接 前面的√取消掉,点击确定完成

  3. nodejs的交互式解释器模式常用命令

    node - 进入交互器交互器解释模式 ctrl + c - 退出当前终端 ctrl + c 按下两次 - 退出 Node REPL ctrl + d - 退出 Node REPL 向上/向下 键 - ...

  4. string.Compare()方法

    判断字符串中是否包含一个值 返回一个值,该值指示指定的 String 对象是否出现在此字符串中. String a = "abcd"; if(source.a("a&qu ...

  5. java之spring之对象的创建

    首先提供目录结构如下: 下面提供各文件代码,以供参考: UserDynamicFactory.java package cn.sxt.factory; import cn.sxt.vo.User; / ...

  6. left join 左边有数据,右边无数据

     参考了链接: https://blog.csdn.net/chenjianandiyi/article/details/52402011   主要是and和where的区别:   原Sql: Con ...

  7. C# vb .net图像合成-合成富文本

    在.net中,如何简单快捷地实现图像合成呢,比如合成文字,合成艺术字,多张图片叠加合成等等?答案是调用SharpImage!专业图像特效滤镜和合成类库.下面开始演示关键代码,您也可以在文末下载全部源码 ...

  8. P2613 【模板】有理数取余 (数论)

    题目 P2613 [模板]有理数取余 解析 简单的数论题 发现并没有对小数取余这一说,所以我们把原式化一下, \[(c=\frac{a}{b})\equiv a\times b^{-1}(mod\ p ...

  9. k8s--yml文件

  10. this指向详解及改变它的指向的方法

    一.this指向详解(彻底理解js中this的指向,不必硬背) 首先必须要说的是,this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,实际上this的最终指向的是 ...