第十六届浙江大学宁波理工学院程序设计大赛 E 雷顿女士与平衡树(并查集)
题意
链接:https://ac.nowcoder.com/acm/contest/2995/E
来源:牛客网
卡特莉正在爬树,此时她又在树梢发现了一个谜题,为了不令她分心以至于发生意外,请你帮她解决这个问题。
具体地来说,我们定义树上从u到v简单路径上所有点权中最大值与最小值的差值为这条路径的"平衡值",记为balance(u,v)。
思路
首先,把这个式子拆成两部分,一部分计算最大值的和,另一部分计算最小值的和。
如何计算最大值的和?
将点按点权从小到大排序,从小到大遍历每个点u,记u为访问过,找u连的点v,如果v访问过了,那么说明v肯定比u小,所以u的权值在这两个集合作为最大值,乘上sz[fu]和sz[fv]即为u对答案的贡献。可能会有疑问为啥要乘上sz[fu],乘上sz[fv]不就是u对v所在集合的贡献吗?实则不然,比如看样例:
1
10
9 9 6 2 4 5 8 5 5 6
2 1
3 1
4 3
5 3
6 4
7 2
8 4
9 5
10 3

蓝色表示每个点按顺序更新后所在集合的sz,当遍历到u=2的时候,发现连的点7和1都访问过,说明权值都是小于等于9的,所以将2和7合并后,u所在集合的sz变成了2,那么2再和1合并时,不仅2可以作为1所在集合的点的最大值,而且7这个点是可以陪着2一起连向1所在集合的,因为最大值依然是2这个点。
对于最小值的和的求法是类似的,按权值从大到小排序……
代码
#include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
#define ll long long
const int N=5e5+5;
const int mod=1e9+7;
const double eps=1e-8;
const double PI = acos(-1.0);
#define lowbit(x) (x&(-x))
int read()
{
int x=0;
char ch=getchar();
while(!isdigit(ch))
{
ch=getchar();
}
while(isdigit(ch))
{
x=x*10+(ch-'0');
ch=getchar();
}
return x;
}
struct node
{
ll x,w;
}a[N];
bool cmp1(node a,node b)
{
return a.w<b.w;
}
bool cmp2(node a,node b)
{
return a.w>b.w;
}
vector<int> g[N];
ll pre[N],mx[N],mn[N],sz[N],vis[N];
ll find(ll x)
{
if(x==pre[x])
return x;
return pre[x]=find(pre[x]);
}
int main()
{
std::ios::sync_with_stdio(false);
int t=read();
while(t--)
{
int n=read();
for(int i=1; i<=n; i++)
{
g[i].clear();
a[i].w=read();
a[i].x=i;
mx[i]=mn[i]=a[i].w;
}
for(int i=1; i<n; i++)
{
int u=read(),v=read();
g[u].push_back(v);
g[v].push_back(u);
}
sort(a+1,a+n+1,cmp1);
for(int i=1; i<=n; i++)
pre[i]=i,sz[i]=1,vis[i]=0;
ll ans1=0;
for(int i=1; i<=n; i++)
{
ll u=a[i].x,fu=find(u);
vis[u]=1;
for(int j:g[u])
{
if(!vis[j]) continue;
int fj=find(j);
pre[fj]=fu;
ans1=(ans1+sz[fu]*sz[fj]%mod*a[i].w%mod)%mod;
(sz[fu]+=sz[fj])%=mod;
}
// cout<<u<<" "<<sz[fu]<<endl;
}
// cout<<ans1<<endl;
sort(a+1,a+1+n,cmp2);
for(int i=1; i<=n; i++)
pre[i]=i,sz[i]=1,vis[i]=0;
ll ans2=0;
for(int i=1; i<=n; i++)
{
int u=a[i].x,fu=find(u);
vis[u]=1;
for(int j:g[u])
{
if(!vis[j]) continue;
int fj=find(j);
pre[fj]=fu;
ans2=(ans2+sz[fu]*sz[fj]%mod*a[i].w%mod)%mod;
(sz[fu]+=sz[fj])%=mod;
}
// cout<<u<<" "<<sz[fu]<<endl;
}
// cout<<ans2<<endl;
cout<<(ans1%mod-ans2%mod+mod)%mod<<endl;
}
return 0;
}
第十六届浙江大学宁波理工学院程序设计大赛 E 雷顿女士与平衡树(并查集)的更多相关文章
- 第十六届浙江大学宁波理工学院程序设计大赛 D 雷顿女士与分队hard version(dp)
题意 链接:https://ac.nowcoder.com/acm/contest/2995/D来源:牛客网 卡特莉接到来自某程序设计竞赛集训队的邀请,来为他们进行分队规划. 现在集训队共有n名选手, ...
- nitacm第十六届浙江大学宁波理工学院程序设计大赛总结
校赛时间:2019.11.30周六下午12:00-16:00 重现赛链接:https://ac.nowcoder.com/acm/contest/2995#question 体验: 11点多到达石鳞大 ...
- 第十六届“二十一世纪的计算”学术研讨会 密西根州立大学教授Anil K. Jain主题演讲
Biometrics---How Do I Know Who You Are? 密西根州立大学教授Anil K. Jain主题演讲" title="第十六届"二十一世纪的 ...
- 第十六届“二十一世纪的计算”学术研讨会 图灵奖获得者Butler W. Lampson主题演讲
Personal Control of Digital Data 图灵奖获得者Butler W. Lampson主题演讲" title="第十六届"二十一世纪的计算&qu ...
- 第十六届“二十一世纪的计算”学术研讨会 牛津大学肿瘤成像学教授Michael Brady主题演讲
Computing and Healthcare 牛津大学肿瘤成像学教授Michael Brady主题演讲" title="第十六届"二十一世纪的计算"学术研讨 ...
- 北京师范大学第十六届程序设计竞赛决赛 I 如何办好比赛
链接:https://www.nowcoder.com/acm/contest/117/I来源:牛客网 如何办好比赛 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32768K,其他 ...
- 西电大第十六届程序设计竞赛 A-GRE
题目描述 不愤不启不悱不发,王萌萌为了能够成功上研,开始刻苦背GRE单词,但是由于她过于刻苦,在背会英语单词的同时,把中文读音忘了.于是王萌萌又开始复习起中文发音,她先从数字开始复习起... ...
- “纽劢科技杯”第十六届同济大学程序设计竞赛暨上海邀请赛同步赛 J-张老师的游戏
传送门 题目描述 在空闲时间,张老师习惯性地和菜哭武玩起了取石子游戏,这次的游戏规则有些不同,在他们面前有n堆石子,其中,第i堆石子的个数为a[i],现在制定规则如下: 从张老师开始, ...
- 北京师范大学第十六届程序设计竞赛决赛-重现赛-B题
一.题目链接 https://www.nowcoder.com/acm/contest/117/B 二.题意 给定一组序列$a_1,a_2,\cdots,a_n$,表示初始序列$b_1,b_2,\cd ...
随机推荐
- VARIANT、 _variant_t、CComVariant、COleVariant、CDBVariant
参考文章 http://blog.163.com/wslngcjsdxdr@126/blog/static/16219623020107634935586/ http://blog.csdn.net/ ...
- JS基础-原型链和继承
创建对象的方法 字面量创建 构造函数创建 Object.create() var o1 = {name: 'value'}; var o2 = new Object({name: 'value'}); ...
- JVM垃圾收集器CMS和G1
CMS(Concurrent Mark Sweep)收集器是一种以获取 最短回收停顿时间 为目标的收集器.采用的是"标记-清除算法",整个过程分为4步 由于整个过程中,并发标记和并 ...
- 【CentOS7】设置静态IP地址
[CentOS7]设置静态IP地址 转载:https://www.cnblogs.com/yangchongxing/p/10645871.html 图像化修改 nmtui 查看当前网卡名称 # if ...
- 学习了JsonSchema,我自定义了一个校验代码
JsonSchema 使用fastjsonschema来校验数据 # 导入验证器 import json import fastjsonschema # 读取schema with open('../ ...
- django基础之day08,分页器从无到有,动态思路解析全过程
*********分页器从无到有的全过程,动态思路解析如下:******** 1.通过book_queryset = models.Book.objects.all()[start_num:end_n ...
- Asp.net 学习记录(一)使用asp.net 构建webAPI接口
此系列使用Asp.net构建前后端分离的博客网站. 创建一个asp.net项目 我们这里使用的是空模板,把Https配置去掉(安全先不配置) 构建webapi接口有很多方法,在这里我们选择最简单的2种 ...
- C#程序编写高质量代码改善的157个建议【10-12】[创建对象时需要考虑是否实现比较器、区别对待==和Equals]
前言 建议10.创建对象时需要考虑是否实现比较器 建议11.区别对待==和Equals 建议12.重写Equals时也要重写GetHashCode 建议10.创建对象时需要考虑是否实现比较器 有对象的 ...
- c++-多态的学习
多态的基本介绍 多态基础 面向对象新求 C++编译器提供的多态解决方案 多态意义.多态成立的是三个条件 多态理论基础 多态面试题强化 多态的理解 C++编译器如何实现多态 重载重写重定义 虚析构函数 ...
- 手写SpringMVC
环境描述 idea java 8 1. POM文件 <?xml version="1.0" encoding="UTF-8"?> <proje ...