第十六届浙江大学宁波理工学院程序设计大赛 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 ...
随机推荐
- java之JVM内存模型
简而言之: 基础数据类型,值是保存在栈中: 引用数据类型,值保存在堆中,栈中保存的是引用数据类型在堆中的地址: 方法区:保存所有的class和static变量:
- Python3 网络基础基础2
目录 subprocess 粘包问题 问题原因 解决问题 上传大文件 UDP协议 SocketServer subprocess 可以通过代码执行操作系统的终端命令, 并返回终端执行命令后的结果 im ...
- Happy Birthday! 今天我 1 周岁生日啦!
2018.09.28,我第 1 天分享文章. 2019.09.28,我连续分享的第 365 天. 今天我 1 周岁啦! 生日意味着一个新的开端, 意味着重新把握生活的机会. 新的一岁,从新头像开始 愿 ...
- webpack安装出错(电脑设置了代理)
安装webpack的时候发现第一句话就报错了,之后查了一下找到原因,原来是因为设置了代理服务原文 ,参考了之后知道是因为代理问题,就按着来做
- 《Java Spring框架》基于IDEA搭建Spring源码
第一步: IDEA :IntelliJ IDEA 2018.1.4 :JDK安装(必须1.8或者以上),IDEA安装(过程省略). 第二步: Gradle:下载地址:https://servic ...
- 使用keepalived做High Available(HA)
原文内容来自于LZ(楼主)的印象笔记,如出现排版异常或图片丢失等问题,可查看当前链接:https://app.yinxiang.com/shard/s17/nl/19391737/eab34383-d ...
- C#基础——break ,continue, return用法
- 在 C# 中使用变量
目录 变量的声明 数据类型 变量的赋值 变量的使用 总结 程序离不开数据.把数字.字母和文字输入计算机,就是希望它利用这些数据完成某些任务.例如,需要计算双十一怎么买才最省钱或者显示购物车里面的商品列 ...
- c++-类与类的关系
类与类的关系 #define _CRT_SECURE_NO_WARNINGS #include <iostream> using namespace std; class A { publ ...
- 【高可用架构】开发机上部署Deploy项目(一)
准备 部署项目的细节可以看这个,传送门Centos 7部署Laravel项目 主机IP:192.168.10.17 [高可用架构]系列链接:待部署的架构介绍 演示 部署Deploy composer ...