题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6133

题意:给你一棵n个节点的二叉树,每个节点有一个提交任务的时间,每个节点总的提交任务的罚时为:提交这个节点和其子树所有的任务,每个任务提交时间的总和为该点的罚时。求每个节点提交完所有任务的最小罚时。

解法:根据题意,我们可以知道每个节点的提交的最小罚时为,按照任务的提交时间从小到大的来提交任务,可以得到最小的罚时。所以我们可以用线段树合并,先建立权值线段树,记录权值区间L到R的所有权值sum与size,线段树上的每一个点的ans为ans[lchild]+ans[rchild]+size[rchild]*sum[lchild]。

现场队友写了Splay合并过了,我下来写线段树合并一直MLE,然后交g++卡过了。。。

#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
const int maxn = 100002;
typedef long long LL;
int n,m,cnt,rt[maxn],a[maxn],b[maxn];
LL ans[maxn];
struct edge{
int v,next;
}E[maxn*2];
int head[maxn], edgecnt;
void init(){
memset(head,-1,sizeof(head));
edgecnt=0;
}
void add(int u, int v){
E[edgecnt].v=v,E[edgecnt].next=head[u],head[u]=edgecnt++;
}
struct node{
int ls,rs,sz;
LL ans,sum;
}T[maxn*18];
int Merge(int u, int v){
if(!u||!v) return u+v;
if(T[u].ls||T[u].rs){
T[u].ls=Merge(T[u].ls,T[v].ls);
T[u].rs=Merge(T[u].rs,T[v].rs);
T[u].sum=T[T[u].ls].sum+T[T[u].rs].sum;
T[u].sz=T[T[u].ls].sz+T[T[u].rs].sz;
T[u].ans=T[T[u].ls].ans+T[T[u].rs].ans+T[T[u].ls].sum*T[T[u].rs].sz;
}
else{
T[u].ans=T[u].ans+T[v].ans+T[u].sum*T[v].sz;
T[u].sum=T[u].sum+T[v].sum;
T[u].sz=T[u].sz+T[v].sz;
}
return u;
}
void dfs(int u, int fa){
for(int i = head[u]; ~i; i=E[i].next){
int v = E[i].v;
if(v!=fa){
dfs(v,u);
Merge(rt[u],rt[v]);
}
}
ans[u]=T[rt[u]].ans;
}
void build(int &node, int l, int r, int pos)
{
node = ++cnt;
T[node].sum=T[node].ans=b[pos];
T[node].sz=1;
T[node].ls=T[node].rs=0;
if(l==r) return;
int mid=(l+r)>>1;
if(pos<=mid) build(T[node].ls, l, mid, pos);
else build(T[node].rs, mid+1, r, pos);
}
int main()
{
int _;
scanf("%d", &_);
while(_--){
cnt=0;
scanf("%d", &n);
init();
for(int i=0; i<maxn; i++) T[i].sz=T[i].ans=T[i].sum=0;
for(int i=1; i<=n; i++) scanf("%d", &a[i]), b[i]=a[i];
sort(b+1,b+n+1);
m = unique(b+1,b+n+1)-b-1;
for(int i=1; i<=n; i++) a[i] = lower_bound(b+1,b+m+1,a[i])-b;
for(int i=1; i<=n; i++) build(rt[i],1,m,a[i]);
for(int i=1; i<n; i++){
int u, v;
scanf("%d%d",&u,&v);
add(u,v);
add(v,u);
}
dfs(1,-1);
for(int i=1; i<=n; i++){
printf("%lld", ans[i]);
if(i!=n) printf(" ");
else printf(" \n");
}
}
return 0;
}

2017多校第8场 HDU 6133 Army Formations 线段树合并的更多相关文章

  1. 2017多校第9场 HDU 6162 Ch’s gift 树剖加主席树

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6162 题意:给出一棵树的链接方法,每个点都有一个数字,询问U->V节点经过所有路径中l < ...

  2. 2019牛客多校第八场 F题 Flowers 计算几何+线段树

    2019牛客多校第八场 F题 Flowers 先枚举出三角形内部的点D. 下面所说的旋转没有指明逆时针还是顺时针则是指逆时针旋转. 固定内部点的答案的获取 anti(A)anti(A)anti(A)或 ...

  3. HDU-DuoXiao第二场hdu 6315 Naive Operations 线段树

    hdu 6315 题意:对于一个数列a,初始为0,每个a[ i ]对应一个b[i],只有在这个数字上加了b[i]次后,a[i]才会+1. 有q次操作,一种是个区间加1,一种是查询a的区间和. 思路:线 ...

  4. [2019杭电多校第三场][hdu6609]Find the answer(线段树)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6609 大致题意是求出每个位置i最小需要将几个位置j变为0(j<i),使得$\sum_{j=1}^ ...

  5. 2017多校第9场 HDU 6170 Two strings DP

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6170 题意:给了2个字符串,其中第2个字符串包含.和*两种特别字符,问第二个字符串能否和第一个匹配. ...

  6. 2017多校第9场 HDU 6161 Big binary tree 思维,类似字典树

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6161 题意: 题目是给一棵完全二叉树,从上到下从左到右给每个节点标号,每个点有权值,初始权值为其标号, ...

  7. 2017多校第9场 HDU 6169 Senior PanⅡ 数论,DP,爆搜

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6169 题意:给了区间L,R,求[L,R]区间所有满足其最小质数因子为k的数的和. 解法: 我看了这篇b ...

  8. 2017多校第10场 HDU 6181 Two Paths 次短路

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6181 题意:给一个图,求出次短路. 解法:我之前的模板不能解决这种图,就是最短路和次短路相等的情况,证 ...

  9. 2017多校第10场 HDU 6180 Schedule 贪心,multiset

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6180 题意:给了一些任务的开始时间和终止时间,现在让我们安排k台及机器,让这些任务在k太机器上最小,并 ...

随机推荐

  1. 【bzoj1202】[HNOI2005]狡猾的商人 带权并查集

    题目描述 刁姹接到一个任务,为税务部门调查一位商人的账本,看看账本是不是伪造的.账本上记录了n个月以来的收入情况,其中第i 个月的收入额为Ai(i=1,2,3...n-1,n), .当 Ai大于0时表 ...

  2. Luogu4899 IOI2018狼人(kruskal重构树+主席树)

    可以发现询问的即是“由起点开始‘只经过编号大于等于l的点’所形成的连通块”与“由终点开始‘只经过编号小于等于r的点’所形成的连通块”是否有交集.于是建出重构树,就可以知道每个询问的连通情况了.现在要知 ...

  3. BZOJ3427 Poi2013 Bytecomputer 【dp】

    题目链接 BZOJ3427 题解 容易发现最终序列一定是\(\{-1,0,1\}\)组成的 因为如果有一个位置不是,那么这个位置一定大于\(1\),那么上一个位置一定为\(1\),所以该位置一定加到过 ...

  4. codeforces的dp专题

    1.(467C)http://codeforces.com/problemset/problem/467/C 题意:有一个长为n的序列,选取k个长度为m的子序列(子序列中不能有位置重复),求所取的k个 ...

  5. 【枚举暴力】【UVA11464】 Even Parity

    传送门 Description 给你一个0/1矩阵,可以将矩阵中的0变成1,问最少经过多少此操作使得矩阵任意一元素四周的元素和为偶数. Input 第一行是一个整数T代表数据组数,每组数据包含以下内容 ...

  6. 爬虫实例——爬取淘女郎相册(通过selenium、PhantomJS、BeautifulSoup爬取)

    环境 操作系统:CentOS 6.7 32-bit Python版本:2.6.6 第三方插件 selenium PhantomJS BeautifulSoup 代码 # -*- coding: utf ...

  7. HDU 1045 dfs

    Fire Net Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Su ...

  8. 洛谷2944 [USACO09MAR]地震损失2Earthquake Damage 2

    https://www.luogu.org/problem/show?pid=2944 题目描述 Wisconsin has had an earthquake that has struck Far ...

  9. 51Nod 1003 阶乘后面0的数量 | 思维

    题意:n的阶乘后面0的个数,如果直接算出阶乘再数0的数量一定会超时的. 因为10=2*5,所以求出5贡献的次数就行. #include "bits/stdc++.h" using ...

  10. HDU 5876 Sparse Graph BFS+set删点

    Problem Description In graph theory, the complement of a graph G is a graph H on the same vertices s ...