题目大意:给你一棵树,每个点有点权a_{i},求$\sum _{i=1}^{n} \sum _{j=i}^{n} f(i,j)$,$f(i,j)$表示i,j,路径上的点的最大权值-最小权值

正解的思路好神啊

正解:

首先,原式可以拆成$\sum _{i=1}^{n} \sum _{j=i}^{n} max(i,j) \; - \; \sum _{i=1}^{n} \sum _{j=i}^{n} min(i,j)$

max的求法和min类似,这里只讨论min的求法

把点按照从大到小排序,依次加入树里

感性理解成以当前点的点权作为最小值,那么这个点会向它周围已经被加入树里的联通块"扩散"去更新答案

答案就是这个点周围(剩余联通块的点数-当前联通块的点数)*点权,然后 剩余点数-当前联通块点数

也可以省去减法步骤,把最终答案除以二

并查集维护联通块即可,算上排序,总时间约为$O(nlogn)$

 #include <queue>
#include <vector>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 1001000
#define ll long long
using namespace std; int gint()
{
int ret=,f=;char c=getchar();
while(c<''||c>''){if(c=='-')f=-;c=getchar();}
while(c>=''&&c<=''){ret=ret*+c-'';c=getchar();}
return ret*f;
}
int n,cte,tim;
int w[N],head[N],use[N];
int fa[N],sz[N];
void init(){for(int i=;i<=n;i++)fa[i]=i,sz[i]=;}
int find_fa(int x){
int y=x,pre;while(fa[y]!=y)y=fa[y];
while(fa[x]!=y){
pre=fa[x],fa[x]=y,x=pre;
}return y;
}
struct node{int id,val;}a[N];
struct Edge{int to,nxt;}edge[N*];
void ae(int u,int v){
cte++;edge[cte].nxt=head[u];
edge[cte].to=v,head[u]=cte;
}
int cmp(node s1,node s2){return s1.val<s2.val;} ll solve1()
{
sort(a+,a+n+,cmp);
int x,y,fx,fy;
init(); ll ans=;
for(int i=;i<=n;i++)
{
ll sum=;x=a[i].id;
for(int j=head[x];j;j=edge[j].nxt){
int v=edge[j].to;
if(use[v]){
fy=find_fa(v);
sum+=sz[fy];
}
}sum++;
for(int j=head[x];j;j=edge[j].nxt){
int v=edge[j].to;
if(use[v]){
fy=find_fa(v);
ans+=1ll*(sum-sz[fy])*sz[fy]*a[i].val;
sum-=sz[fy];
fa[fy]=x,sz[x]+=sz[fy];
}
}
use[x]=;
}return ans;
}
ll solve2()
{
memset(use,,sizeof(use));
int x,y,fx,fy;
init(); ll ans=;
for(int i=n;i>=;i--)
{
ll sum=;x=a[i].id;
for(int j=head[x];j;j=edge[j].nxt){
int v=edge[j].to;
if(use[v]){
fy=find_fa(v);
sum+=sz[fy];
}
}sum++;
for(int j=head[x];j;j=edge[j].nxt){
int v=edge[j].to;
if(use[v]){
fy=find_fa(v);
ans+=1ll*(sum-sz[fy])*sz[fy]*a[i].val;
sum-=sz[fy];
fa[fy]=x,sz[x]+=sz[fy];
}
}
use[x]=;
}return ans;
} int main()
{
scanf("%d",&n);
int x,y;
for(int i=;i<=n;i++)
w[i]=a[i].val=gint(),a[i].id=i;
for(int i=;i<n;i++)
x=gint(),y=gint(),ae(x,y),ae(y,x);
ll ans1=solve1();
ll ans2=solve2();
printf("%I64d\n",ans1-ans2);
return ;
}

CF915F Imbalance Value of a Tree (并查集)的更多相关文章

  1. 【CodeForces】915 F. Imbalance Value of a Tree 并查集

    [题目]F. Imbalance Value of a Tree [题意]给定n个点的带点权树,求所有路径极差的和.n,ai<=10^6 [算法]并查集 [题解]先计算最大值的和,按点权从小到大 ...

  2. [CF915F]Imbalance Value of a Tree

    [CF915F]Imbalance Value of a Tree 题目大意: 一棵\(n(n\le10^6)\)个结点的树,每个结点有一个权值\(w_i\).定义\(I(i,j)\)为\(i\)到\ ...

  3. Hdu.1325.Is It A Tree?(并查集)

    Is It A Tree? Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) To ...

  4. Is It A Tree?(并查集)

    Is It A Tree? Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 26002   Accepted: 8879 De ...

  5. CF109 C. Lucky Tree 并查集

    Petya loves lucky numbers. We all know that lucky numbers are the positive integers whose decimal re ...

  6. HDU 5606 tree 并查集

    tree 把每条边权是1的边断开,发现每个点离他最近的点个数就是他所在的连通块大小. 开一个并查集,每次读到边权是0的边就合并.最后Ans​i​​=size[findset(i)],size表示每个并 ...

  7. [Swust OJ 856]--Huge Tree(并查集)

    题目链接:http://acm.swust.edu.cn/problem/856/ Time limit(ms): 1000 Memory limit(kb): 10000 Description T ...

  8. Codeforces Round #363 (Div. 2)D. Fix a Tree(并查集)

    D. Fix a Tree time limit per test 2 seconds memory limit per test 256 megabytes input standard input ...

  9. Is It A Tree?(并查集)(dfs也可以解决)

    Is It A Tree? Time Limit:1000MS     Memory Limit:10000KB     64bit IO Format:%I64d & %I64u Submi ...

随机推荐

  1. 使用CablleStatement调用存储过程

    /** * 使用CablleStatement调用存储过程 * @author APPle * */ public class Demo1 { /** * 调用带有输入参数的存储过程 * CALL p ...

  2. 路飞学城Python-Day23(practise)

    本章总结 练习题 什么是C/S架构? 互联网协议是什么?分别介绍五层协议中每一层的功能? 基于tcp协议通信,为何建立链接需要三次握手,而断开链接却需要四次挥手 为何基于tcp协议的通信比基于udp协 ...

  3. java+jxls利用excel模版进行导出

    大多时候会出现需要导出excel的功能,利用poi可以实现简单的导出,可以说poi的功能非常强大可以做到细节的定制化操作,但相对于在office操作excel,利用poi完全生成excel会显得非常复 ...

  4. 机器学习实战笔记--AdaBoost(实例代码)

    #coding=utf-8 from numpy import * def loadSimpleData(): dataMat = matrix([[1. , 2.1], [2. , 1.1], [1 ...

  5. npx命令

    npx命令 查了一下, 英文资料: https://www.npmjs.com/package/npx 中文资料: 什么是npx 第一次看到npx命令是在 babel 的文档里 Note: If yo ...

  6. laravel contains 的用法

    最近在学laravel,做一下学习笔记. 1.contains()方法判断集合是否包含给定的项目: ]);var_dump($collection->contains('Desk'));// t ...

  7. 安装idea

    1.下载idea https://www.jetbrains.com/idea/download/#section=linux 2.解压 sudo tar -zxvf  ideaIC-2018.3.2 ...

  8. HBase入门操作 常用命令和增删改查的简单应用操作

    这里启动关闭Hadoop和HBase的顺序一定是: 启动Hadoop—>启动HBase—>关闭HBase—>关闭Hadoop ssh localhost 开启hadoopcd /us ...

  9. XPATH怎么获取TITLE中有中文的标签

    定位 //*[@id="kkpager"]/div[1]/span[1]/a[@title="下一页"] 获取元素 txt4 = txt.xpath('//*[ ...

  10. python 网络编程 粘包问题

    1.粘包现象 TCP粘包是指发送方发送的若干包数据到接收方接收时粘成一包,从接收缓冲区看,后一包数据的头紧接着前一包数据的尾.   粘包出现原因 使用了优化方法(Nagle算法),将多次间隔较小.数据 ...