给你一棵有n个节点的二叉树,每个节点有一个权值,对于一棵子树u,将u的子树中的节点权值从大到小排序,令sz[u]为子树u的大小,

则ans[u] = 1 * a[1] + 2 * a[2] + ... + sz[u] * a[sz[u]],其中a[1] >= a[2] >= ... >= a[u]。求所有节点的答案。

对每个节点建立权值线段树,dfs整棵树,线段树合并

ans[rt] = ans[ls[rt]] + ans[rs[rt]] + size[ls[rt]] * w[rs[rt]],w表示某权值区间的权值和,size表示某权值区间内点的个数。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int maxn = 1e5 + ;
const int maxnode = 2e6 + ;
struct edge { int to, next; }e[maxn << ];
int head[maxn], ecnt;
void edge_init() { ecnt = ; memset(head, -, sizeof(head)); }
void add(int u, int v) {
e[ecnt].to = v; e[ecnt].next = head[u]; head[u] = ecnt++;
}
int a[maxn], b[maxn];
int root[maxn];
int sz[maxnode], ls[maxnode], rs[maxnode];
long long ans[maxnode], sum[maxnode];
int tot, m; int mergeleaf(int u, int v) {
sz[u] += sz[v];
sum[u] += sum[v];
ans[u] = sum[u] / (long long)sz[u] * (long long) sz[u] * (long long) (sz[u] + 1LL) / 2LL;
return u;
} int merge(int u, int v, int l, int r) {
if (!u || !v) return u | v;
if (l == r) return mergeleaf(u, v);
int mid = (l + r) >> ;
ls[u] = merge(ls[u], ls[v], l, mid);
rs[u] = merge(rs[u], rs[v], mid + , r);
sz[u] = sz[ls[u]] + sz[rs[u]];
sum[u] = sum[ls[u]] + sum[rs[u]];
ans[u] = ans[ls[u]] + ans[rs[u]] + sum[ls[u]] * (long long) sz[rs[u]];
return u;
} void update(int x, int &rt, int l, int r) {
if (!rt) rt = ++tot;
sum[rt] = ans[rt] = (long long) b[x];
sz[rt] = ;
if (l == r) return;
int mid = (l + r) >> ;
if (x <= mid) update(x, ls[rt], l, mid);
else update(x, rs[rt], mid + , r);
} void dfs(int u, int fa) {
update(a[u], root[u], , m);
for (int i = head[u]; i != -; i = e[i].next) {
int v = e[i].to;
if (v == fa) continue;
dfs(v, u);
root[u] = merge(root[u], root[v], , m);
}
} int main() {
int T, n;
scanf("%d", &T);
while (T--) {
edge_init();
scanf("%d", &n);
for (int i = ; i <= n; ++i) scanf("%d", a + i), b[i] = a[i];
sort(b + , b + + n);
m = unique(b + , b + + n) - (b + );
for (int i = ; i <= n; ++i) a[i] = lower_bound(b + , b + + m, a[i]) - b;
for (int u, v ,i = ; i < n; ++i) {
scanf("%d%d", &u, &v);
add(u, v); add(v, u);
}
tot = ;
memset(root, , sizeof(root));
dfs(, );
for (int i = ; i <= n; ++i) printf("%lld ", ans[root[i]]);
puts("");
for (int i = ; i <= tot; ++i) ls[i] = rs[i] = sum[i] = ans[i] = sz[i] = ;
}
}
 

hdu6133 Army Formations 线段树合并的更多相关文章

  1. 2017多校第8场 HDU 6133 Army Formations 线段树合并

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6133 题意:给你一棵n个节点的二叉树,每个节点有一个提交任务的时间,每个节点总的提交任务的罚时为:提交 ...

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

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

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

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

  4. 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). 复杂度看起来不高, ...

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

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

  6. bzoj 2243 [SDOI2011]染色(树链剖分+线段树合并)

    [bzoj2243][SDOI2011]染色 2017年10月20日 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询 ...

  7. bzoj3702二叉树 线段树合并

    3702: 二叉树 Time Limit: 15 Sec  Memory Limit: 256 MBSubmit: 600  Solved: 272[Submit][Status][Discuss] ...

  8. BZOJ_2212_[Poi2011]Tree Rotations_线段树合并

    BZOJ_2212_[Poi2011]Tree Rotations_线段树合并 Description Byteasar the gardener is growing a rare tree cal ...

  9. B20J_2733_[HNOI2012]永无乡_权值线段树合并

    B20J_2733_[HNOI2012]永无乡_权值线段树合并 Description:n座岛,编号从1到n,每座岛都有自己的独一无二的重要度,按照重要度可以将这n座岛排名,名次用1到 n来表示.某些 ...

随机推荐

  1. word简单优化--提高效率

    1.文件 ---选项---校对(去掉下面这些项) 2.点击自动更正,去掉如下 3.文件--选项--保存

  2. 2、jeecg 笔记之 t:dictSelect 或 t:dgCol 自定义字典

    1.需求 先说一下需求场景吧,我们知道 jeecg 中提供了下拉,其中包含两种使用场景: 一种是直接通过 t:dictSelect 使用,再就是 t:dgCol  用于表头的列表工具条标签: 总之就是 ...

  3. Cisco Packet Tracer

    ---恢复内容开始--- 1.简单局域网组建 交换机:2960  s1 终端设备:generic  pc 配置 pc1    单击>>Descktop>>IP configur ...

  4. C#-----类FileStream的使用

    1.枚举类FileMode 指定操作系统打开文件的方式 CreateNew  指定操作系统应创建一个新的文件 Create  指定操作系统应创建一个新的文件. 如果该文件已存在,则会覆盖它 Open  ...

  5. os.path.join

    os.path.join()函数: 第一个以”/”开头的参数开始拼接,之前的参数全部丢弃. 以上一种情况为先.在上一种情况确保情况下,若出现”./”开头的参数,会从”./”开头的参数的上一个参数开始拼 ...

  6. codeforces 982B Bus of Characters

    题意: 有n排座位,每排有两个座位,每排座位的宽度都不一样. 有2 * n个人要上车,如果是内向的人,那么它会选择一排两个都是空位并且宽度最小的一排去坐: 如果是外向的人,会选择一排座位已经有人坐的, ...

  7. ftp权限设置大全!!!

    1.登录和对匿名用户的设置write_enable=YES                         //是否对登录用户开启写权限.属全局性设置.默认NOlocal_enable=YES    ...

  8. iOS项目之交换方法(runtime)

    在项目中,经常会遇到系统自带的方法满足不了自己的需求,往往我们解决这种情况的时候,都是在分类中添加一个方法.然而很多时候,项目已经开发很长时间了,如果一个一个的去替换系统的方法,太浪费宝贵的时间,所以 ...

  9. Maven Web Projest经Update Projest报错:Cannot nest 'myApp/src/main/resource' inside 'myApp/src'. To enable the nesting exclude 'main/' from 'myApp/src'

    1,报错场景 2,解决方法 修改pom.xml,去掉该行:<sourceDirectory>src/</sourceDirectory>

  10. MySQL中SQL语句2

    上一片介绍了一些基本的SQL的增删改查,这一片会介绍一些进阶的SQL语句使用. MySQL中的视图 视图是什么?当我们总是查询几张表的某个字段时,可以创建一张虚拟表,把这几个字段写入这个虚拟的表,这样 ...