HDU多校6821A Very Easy Graph Proble
确实是一个非常简单的问题…
首先很容易看出边的权值是很特殊的
换而言之,就算把[1,i−1][1,i-1][1,i−1]条边走个遍,也比走第iii条边划算
所以我们想到建立最小生成树,因为一旦边权小的把两个点连起来
一定是最优的,后面的边加进来对这两点没有影响
所以就变成了求树上任意两异色点距离和所以就变成了求树上任意两异色点距离和所以就变成了求树上任意两异色点距离和
可以算每条边的贡献,计算左右两边的白黑点对,相乘即可可以算每条边的贡献,计算左右两边的白黑点对,相乘即可可以算每条边的贡献,计算左右两边的白黑点对,相乘即可
但我脑子抽了,用的树型dp完成但我脑子抽了,用的树型dp完成但我脑子抽了,用的树型dp完成
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int mod=1e9+7;
const int maxn=1e5+10;
int n,m,L[maxn],R[maxn],pre[maxn],a[maxn],q;
struct edge{int to,nxt,w;
}d[maxn<<1]; int head[maxn<<1],cnt=1;
void add(int u,int v,int w){d[++cnt]=(edge){v,head[u],w},head[u]=cnt;d[++cnt]=(edge){u,head[v],w},head[v]=cnt;
}
int find(int x){return x==pre[x]?x:pre[x]=find(pre[x]);
}
int siz[maxn][2],dp[maxn],w[maxn<<1];
void kur()
{int j=1;for(int i=1;i<n;i++)for(;j<=m;j++){int l=L[j],r=R[j];if( find(l)==find(r) ) continue;pre[find(l)]=find(r);add(l,r,w[j]);break;}
}
void dfs(int u,int fa)
{siz[u][0]=( a[u]==0 );siz[u][1]=( a[u]==1 );dp[u]=0;for(int i=head[u];i;i=d[i].nxt ){int v=d[i].to;if( v==fa ) continue;dfs(v,u);dp[u]+=dp[v]+siz[v][0]*d[i].w%mod;dp[u]%=mod;//u的子树中所有0到u的总距离 siz[u][0]+=siz[v][0];siz[u][1]+=siz[v][1];}
}
void DP(int u,int fa)
{for(int i=head[u];i;i=d[i].nxt ){int v=d[i].to;if( v==fa ) continue;dp[v]=dp[u]+( q-siz[v][0]-siz[v][0] )*d[i].w%mod;dp[v]=(dp[v]%mod+mod)%mod;DP(v,u);}
}
signed main()
{int t; cin >> t;w[0]=1;for(int i=1;i<=2e5;i++)w[i]=w[i-1]*2%mod;while( t-- ){cin >> n >> m;q=0;for(int i=1;i<=n;i++){scanf("%lld",&a[i]),pre[i]=i;q+=( a[i]==0 );}for(int i=1;i<=m;i++)scanf("%lld%lld",&L[i],&R[i]);kur();dfs(1,0);DP(1,0);int ans=0;for(int i=1;i<=n;i++)if( a[i] ) ans=(ans+dp[i])%mod;ans=(ans%mod+mod)%mod;cout << ans << endl; cnt=1;for(int i=1;i<=n;i++) head[i]=0;}
}
HDU多校6821A Very Easy Graph Proble相关推荐
- 2018 HDU多校第四场赛后补题
2018 HDU多校第四场赛后补题 自己学校出的毒瘤场..吃枣药丸 hdu中的题号是6332 - 6343. K. Expression in Memories 题意: 判断一个简化版的算术表达式是否 ...
- 权值线段树小结(hdu多校,普通平衡树,郁闷的出纳员)
之前刷了一点主席树的题目,但是没有系统的做过权值线段树的题目.主席树是多根权值线段树的综合.权值线段树可以解决在总区间里求第k大的问题.在普通的线段树里,我们每一个节点维护的是权值大小.但是在权值线段 ...
- HDU 多校 6400 Parentheses Matrix(构造)
HDU 多校 6400 Parentheses Matrix(构造) // Problem: D. Parentheses Matrix // Contest: Codeforces - 2018 C ...
- HDU多校4 - 6989 Didn‘t I Say to Make My Abilities Average in the Next Life?!(单调栈)
题目链接:点击查看 题目大意:给出一个长度为 nnn 的序列,再给出 mmm 次询问,每次询问给出一个区间 [l,r][l,r][l,r],要求输出区间 [l,r][l,r][l,r] 内 " ...
- HDU多校4 - 6992 Lawn of the Dead(线段树+模拟)
题目链接:点击查看 题目大意:给出一个 n∗mn*mn∗m 的矩阵,有 kkk 个点被 banbanban 掉了,现在从点 (1,1)(1,1)(1,1) 出发,只能向右或向下移动,问可以到达的点有多 ...
- HDU多校1 - 6959 zoto(莫队+树状数组/值域分块)
题目链接:点击查看 题目大意:在二维平面内有 nnn 个点,表示为 (i,f[i])(i,f[i])(i,f[i]),需要回答 mmm 次询问,每次询问会给出一个矩形,问矩形内有多少个不同的 yyy ...
- HDU多校3 - 6975 Forgiving Matching(多项式匹配字符串)
题目链接:点击查看 题目大意:给出一个长度为 nnn 的字符串 sss 和一个长度为 mmm 的字符串 ttt.规定 kkk 匹配的意思是,两个长度相同的字符串至多有 kkk 个位置是不同的,特别的, ...
- HDU多校1 - 6955 Xor sum(字典树+贪心)
题目链接:点击查看 题目大意:给出一个长度为 nnn 的序列,要求找到一段长度最短的区间,使得异或和大于等于 kkk,如果有多种答案,输出左端点最小的那个 题目分析:倒着维护一下后缀异或和,将后缀异或 ...
- Swaps and Inversions hdu多校训练第二场 树状数组求逆序数+离散化
http://acm.hdu.edu.cn/showproblem.php?pid=6318 交换相邻的元素,有几个逆序对,就交换几次使其变成顺序对 #include<bits/stdc++.h ...
最新文章
- java手机音乐文件夹,从原始文件夹打开音乐文件,使用Android上的意图在设备的默认应用程序上播放...
- java对象布局查看工具_Java 查看对象布局工具 - Java Object Layout
- 5件最灵异的事~~~~~~~~~~~~~~~~~~转
- 能不能用python开发qq_用Python写一个模拟qq聊天小程序的代码实例
- webstorm 破解方式
- 操作系统学习笔记以及个人见解
- FLOPs和模型参数计算
- 二阶系统响应指标图_二阶系统的性能指标
- 原生 android 手机,三部具有原生安卓系统的旗舰手机,一部比一部漂亮
- helm --set的使用示例及基本使用命令整理
- minIO安装教程及代码使用
- 时区 夏令时造成的问题
- switch判断语句用法
- NandFlash 驱动分析与基础功能实现
- R语言做GGEbiplot_基于R语言的GGE双标图在大豆区试中的应用
- 使用Eclipse创建最简单的JavaWeb网页项目
- php中文网教程 百度云,网盘直链问题请教
- 高质量 C++/C 编程指南
- 计算机科学领域专业,计算机科学与技术专业主要包括哪些领域?
- Navicat安装及pj