ZR1050
ZR1050
http://www.zhengruioi.com/problem/1030
题目大意:
给定一棵带点权的树,求所有联通块的点权和的平方的和 \(n \le 10^5\)
题解
首先,关于平方的和或者和的平方我们一般都是考虑新加进来一个点会产生什么样的贡献
比如这一题,我们考虑合并两个集合的代价会发生什么样的变化
首先,设\(a,b\)分别为合并的两个集合的点权和
那么由$a^2 \(变为\)(a + b) ^ 2$的区别是代价多了个\(2ab\)和\(b^2\)
也就是说我们在DP的过程中需要维护所有联通块的点权和进行转移
接下,直接暴力计算是不可以的,我们需要对所有的联通块统一计算,发现对于合并每一对联通块的代价都是上面的东西
乘法分配律之后
我们发现还要额外记录当前点为根的联通块个数
设\(f_i\)表示以\(i\)点为根的联通块的个数
设\(g_i\)表示\(i\)点为根的所有联通块的点权和
设\(h_i\)表示以\(i\)点为根的所有联通块的点权和的平方的和
那么首先根据上面,我们在树形DP的时候可以合并两个联通块
\]
首先本来原有的联通块的代价肯定是要保留,另外,对于\(h_x\)可以被合并\(f_y\)次,同理\(h_y\)会被合并\(f_y\)次
最后由于\(g\)数组记录的本来就是总贡献,因此直接合并即可
同理我们可以得到\(g\)的转移
\]
最后更新答案即可
总结
对于这种和联通块有关的题目一般可以通过单独算贡献或者DP的方式解决
特别是和平方相关的,要考虑新加进来的数的贡献
代码
#include<cstdio>
#include<iostream>
#include<queue>
#include<algorithm>
#include<cstring>
#include<cctype>
#include<vector>
#include<ctime>
#include<cmath>
#include<set>
#include<map>
#define LL long long
#define pii pair<int,int>
#define mk make_pair
#define fi first
#define se second
using namespace std;
const int N = 2e5 + 3;
const LL mod = 998244353;
int n;
LL w[N];
LL f[N],g[N],h[N];
vector <int> G[N];
inline int read(){
int v = 0,c = 1;char ch = getchar();
while(!isdigit(ch)){
if(ch == '-') c = -1;
ch = getchar();
}
while(isdigit(ch)){
v = v * 10 + ch - 48;
ch = getchar();
}
return v * c;
}
inline void dfs(int x,int fa){//h:平方的和
f[x] = 1;g[x] = w[x];
h[x] = w[x] * w[x] % mod;
for(int i = 0;i < (int)G[x].size();++i){
int y = G[x][i];
if(y == fa) continue;
dfs(y,x);
h[x] = (h[x] + h[x] * f[y] % mod + 2 * g[x] * g[y] % mod + h[y] * f[x] % mod) % mod;
g[x] = (g[x] + g[x] * f[y] + g[y] * f[x]) % mod;
f[x] = (f[x] + f[x] * f[y]) % mod;
}
}
int main(){
n = read();
for(int i = 1;i <= n;++i) w[i] = read();
for(int i = 1;i < n;++i){
int x = read(),y = read();
G[x].push_back(y);
G[y].push_back(x);
}
dfs(1,0);
LL ans = 0;
for(int i = 1;i <= n;++i) ans = (ans + h[i]) % mod;
cout << ans;
return 0;
}
ZR1050的更多相关文章
随机推荐
- Spring+Stomp+ActiveMq实现websocket长连接
stomp.js+spring+sockjs+activemq实现websocket长连接,使用java配置. pom.xml(只列出除了spring基本依赖意外的依赖,spring-version为 ...
- 杨柳目-杨柳科-Info-新闻:注意了!杨絮解决有办法了
ylbtech-杨柳目-杨柳科-Info-新闻:注意了!杨絮解决有办法了 1.返回顶部 1. 注意了!杨絮解决有办法了 2018-05-03 14:18 昨天中午经过一个理发店,门口蹲了个染黄发.系 ...
- hdu1532&&poj1273 最大流
Dinic算法: 层次图:根据源点到该点的距离建图,这里设相邻的都差1. (下面部分转) 在这幅图中我们首先要增广1->2->4->6,这时可以获得一个容量为2的流,但是如果不建立4 ...
- docker安装 2016-11-06 19:14 299人阅读 评论(31) 收藏
Docker支持运行在以下CentOS版本: CentOS 7.X 安装在二进制兼容的EL7版本如 Scientific Linux也是可能成功的,但是Docker 没有测试过并且不官方支持. 此文带 ...
- Linus 本尊也来了!为什么 KubeCon 越来越火了?
2015年11月,第一届 KubeCon 在美国旧金山开始的时候,还只是个200人的小会议,2019年的7月,KubeCon 第二次在中国举办,就有 3500 多位云原生和开源领域工程师齐聚一堂. 连 ...
- Apache利用mod_limitipconn模块限制客户端多线程下载
由于网站几次被人以搞并发弄跨了,所以百度了一堆方法.其中有一篇针对apache的能限制ip访问量.不允许同一ip大并发访问. 安装模块 yum install mod_limitipconn.x86_ ...
- jQuery Callback
Callback 函数在当前动画 100% 完成之后执行. jQuery 动画的问题 许多 jQuery 函数涉及动画.这些函数也许会将 speed 或 duration 作为可选参数. 例子:$(& ...
- Jmeter监控
https://www.cnblogs.com/saryli/p/6596647.html JMeter是一款压力测试工具,我们也可以用它来监控服务器资源使用情况. JMeter正常自带可以通过Tom ...
- oracle函数 sysdate
[功能]:返回当前日期. [参数]:没有参数,没有括号 [返回]:日期 [示例]select sysdate hz from dual; 返回:2008-11-5
- oracle函数 mod(x,y)
[功能]返回x除以y的余数 [参数]x,y,数字型表达式 [返回]数字 [示例] select mod(23,8),mod(24,8) from dual; 返回:7,0