[CF915F]Imbalance Value of a Tree
[CF915F]Imbalance Value of a Tree
题目大意:
一棵\(n(n\le10^6)\)个结点的树,每个结点有一个权值\(w_i\)。定义\(I(i,j)\)为\(i\)到\(j\)之间简单路径上最大权值与最小权值之差,求\(\displaystyle\sum_{i=1}^n\sum_{j=1}^nI(i,j)\)。
思路:
分别计算路径最大权值之和与最小权值之和。以最大权值之和为例,在图中按权值从大到小枚举每一个点,则对于该连通块中每一个经过该点的路径,该点为路径上权值最大的点,可以计算该点对答案的贡献,并将计算完贡献的点从图中删去。
由于删点是一个难以实现的操作,因此可以将操作改为加点操作,用并查集维护连通性即可。最小权值和同理。时间复杂度\(\mathcal O(n\log n)\)。
源代码:
#include<cstdio>
#include<cctype>
#include<numeric>
#include<algorithm>
#include<forward_list>
using int64=long long;
inline int getint() {
register char ch;
while(!isdigit(ch=getchar()));
register int x=ch^'0';
while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
return x;
}
constexpr int N=1e6+1;
int seq[N],pos[N],w[N];
std::forward_list<int> e[N];
inline void add_edge(const int &u,const int &v) {
e[u].emplace_front(v);
e[v].emplace_front(u);
}
struct DisjointSet {
int anc[N],size[N];
void reset(const int &n) {
std::fill(&size[1],&size[n+1],1);
std::iota(&anc[1],&anc[n+1],1);
}
int find(const int &x) {
return x==anc[x]?x:anc[x]=find(anc[x]);
}
void merge(const int &x,const int &y) {
size[find(y)]+=size[find(x)];
anc[find(x)]=find(y);
}
};
DisjointSet s;
int main() {
const int n=getint();
for(register int i=1;i<=n;i++) w[i]=getint();
for(register int i=1;i<n;i++) {
add_edge(getint(),getint());
}
int64 max=0,min=0;
s.reset(n);
std::iota(&seq[1],&seq[n+1],1);
std::sort(&seq[1],&seq[n+1],[](const int &a,const int &b){return w[a]<w[b];});
for(register int i=1;i<=n;i++) pos[seq[i]]=i;
for(register int i=1;i<=n;i++) {
const int &x=seq[i];
int64 last=1,tmp=0;
for(register auto &y:e[x]) {
if(pos[y]>pos[x]) continue;
tmp+=last*s.size[s.find(y)];
last+=s.size[s.find(y)];
s.merge(x,y);
}
max+=(int64)w[x]*tmp;
}
s.reset(n);
std::iota(&seq[1],&seq[n+1],1);
std::sort(&seq[1],&seq[n+1],[](const int &a,const int &b){return w[a]>w[b];});
for(register int i=1;i<=n;i++) pos[seq[i]]=i;
for(register int i=1;i<=n;i++) {
const int &x=seq[i];
int64 last=1,tmp=0;
for(register auto &y:e[x]) {
if(pos[y]>pos[x]) continue;
tmp+=last*s.size[s.find(y)];
last+=s.size[s.find(y)];
s.merge(x,y);
}
min+=(int64)w[x]*tmp;
}
printf("%lld\n",max-min);
return 0;
}
[CF915F]Imbalance Value of a Tree的更多相关文章
- CF915F Imbalance Value of a Tree (并查集)
题目大意:给你一棵树,每个点有点权a_{i},求$\sum _{i=1}^{n} \sum _{j=i}^{n} f(i,j)$,$f(i,j)$表示i,j,路径上的点的最大权值-最小权值 正解的思路 ...
- Codeforces 915F Imbalance Value of a Tree
Imbalance Value of a Tree 感觉这种题没啥营养, 排个序算算贡献就好啦. #include<bits/stdc++.h> #define LL long long ...
- 【CodeForces】915 F. Imbalance Value of a Tree 并查集
[题目]F. Imbalance Value of a Tree [题意]给定n个点的带点权树,求所有路径极差的和.n,ai<=10^6 [算法]并查集 [题解]先计算最大值的和,按点权从小到大 ...
- Codeforces 915F Imbalance Value of a Tree(并查集)
题目链接 Imbalance Value of a Tree 题意 给定一棵树.求树上所有简单路径中的最大权值与最小权值的差值的和. 首先考虑求所有简单路径中的最大权值和. 对所有点按照权值大小升 ...
- Codeforces 915 F. Imbalance Value of a Tree(并查集)
F. Imbalance Value of a Tree 题意: 给一颗带点权的树,求所有简单路径上最大点权和最小点权之差的总和. 思路: 所求问题可以看作求各路径上的最大值之和减各路径上的最小值之和 ...
- Imbalance Value of a Tree CodeForces - 915F
链接 大意: 给定树, 求树上所有链上最大值最小值之差 817D的树上版本, 用并查集维护即可. 817D由于是链的情况并查集不必压缩路径即可达到均摊$O(n)$, 该题必须压缩, 复杂度$O(nlo ...
- Codeforces915F. Imbalance Value of a Tree
n<=1e6的树问所有路径的极差之和. 被遗忘的套路...以后绝对不会再忘了QAQ 只要算最大值之和即可,最小值同理.数字从大到小排序(反正都是要排序的,如果从大到小不行等会反过来试试),然后逐 ...
- 记第一场cf比赛(Codeforces915)
比赛感想 本来21:05开始的比赛,结果记成21:30了...晚了25分钟才开始[捂脸] 这次是Educational Round,所以还比较简单. 前两道题一眼看去模拟+贪心,怕错仔细看了好几遍题, ...
- [数据结构]——二叉树(Binary Tree)、二叉搜索树(Binary Search Tree)及其衍生算法
二叉树(Binary Tree)是最简单的树形数据结构,然而却十分精妙.其衍生出各种算法,以致于占据了数据结构的半壁江山.STL中大名顶顶的关联容器--集合(set).映射(map)便是使用二叉树实现 ...
随机推荐
- ionic改tab文字和icon图片的颜色
The official way would be: Change in your theme/variables.scss Active icon for tabs on android is: $ ...
- Kafka自我学习1-Multi-broker cluster
====================================Testing environment =========================================== ...
- java迭代map
java迭代map: import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.ut ...
- [洛谷P2124] 奶牛美容
洛谷题目链接:奶牛美容 题目描述 输入输出格式 输入格式: 输出格式: 输入输出样例 输入样例#1: 6 16 ................ ..XXXX....XXX... ...XXXX... ...
- RGB颜色原理
参考:http://www.cnblogs.com/harrytian/archive/2012/12/12/2814210.html 工作中经常和颜色打交道,但却从来没有从原理上了解一下,这篇文章希 ...
- 51nod K 汽油补给 大根堆+小根堆....
题目传送门 用优先队列瞎搞... 想着在每个地方 先算上一个点到这一个点要花费多少钱 这个用小根堆算就好 然后在这个地方加油 把油钱比自己多的替代掉 这个用大根堆维护一下 然后两个堆之间信息要保持互通 ...
- NYOJ 38 布线问题 (最小生成树 prim)
题目链接 描述 南阳理工学院要进行用电线路改造,现在校长要求设计师设计出一种布线方式,该布线方式需要满足以下条件: 1.把所有的楼都供上电. 2.所用电线花费最少 输入 第一行是一个整数n表示有n组测 ...
- [ CodeVS冲杯之路 ] P2456
不充钱,你怎么AC? 题目:http://codevs.cn/problem/2456/ 用贪心的思想,木材当然要尽量分成多的木板,而大的木材能够分成大木板,但是小的木材不一定能够分成大的木板,所以木 ...
- mongodb的数据库操作
1.创建数据库 语法 MongoDB 创建数据库的语法格式如下: use DATABASE_NAME 如果数据库不存在,则创建数据库,否则切换到指定数据库. 1.创建数据库 > show dbs ...
- USB接口无法识别设备
http://windows.microsoft.com/zh-cn/windows/answers?tId=14fa1e44-0a19-48ef-9ba7-b7e512a837a4 小琼子 提问 2 ...