2019 沈阳网络赛 D Fish eating fruit ( 树形DP)
题意:求一颗树中所有点对(a,b)的路径长度,路径长度按照模3之后的值进行分类,最后分别求每一类的和
分析:树形DP
\(dp[i][j]\) 表示以 i 为根的子树中,所有子节点到 i 的路径长度模3等于 j 的路径之和
\(c[i][j]\) 表示以 i 为根的子树中,所有子节点到 i 的路径长度模3等于 j 的点数
\(ok[i][j]\) 表示以 i 为根的子树中,是否有子节点到 i 的路径长度模3等于 j
每次只考虑所有经过根 x 的路径,并且路径的一个端点在 x 的一颗子树上,另一个端点在 x 的另一颗子树上。(可以想到其他所有情况都可以在考虑 x 的子树结点或者是x的祖先结点时被考虑到)
假设当前枚举到 x 的子节点 y,之前遍历的子节点已经使得三个数组更新。那么我们假设要计算的路径的起点在 y ,要计算的路径的终点在之前遍历过的子节点中。
计算答案贡献:
关于x-y的连边的贡献为
\(c[x][a] * c[y][b] * edge\)
关于起点到 y 的所有路径长度的贡献为
\(c[x][a] * dp[y][b]\)
关于x到终点的所有路径长度的贡献为
\(c[y][b] * dp[x][a]\)
最终边权所属分类为\((a+b+edge) \% 3\) 累加到答案即可
关于更新 x
用 y 来更新 x
\(dp[x][(a+edge)\%3] += dp[y][a] + edge * c[y][a]\)
\(ok[x][(a+edge)\%3] = true\)
\(c[x][(a+edge)\%3] += c[y][a]\)
当然点分治也可以做,但是复杂度就不是很优秀了
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 10010;
const int M = 200010;
const ll mod = 1e9 + 7;
int head[N],ver[M],nxt[M],tot;
int x,y,n;
bool ok[N][3];
ll edge[M],z,dp[N][3],c[N][3];
ll ans[3];
void add(int x,int y,ll z){
ver[++tot] = y;edge[tot] = z;nxt[tot] = head[x];head[x] = tot;
}
void dfs(int x,int fa){
for(int i=head[x];i;i=nxt[i]){
int y = ver[i];
if(y == fa)continue;
dfs(y,x);
ll z = edge[i];
for(int j=0;j<3;j++){
for(int k=0;k<3;k++){
if(ok[x][j] && ok[y][k]){
ans[(j+k+z)%3] += (dp[x][j] * c[y][k]% mod + dp[y][k] * c[x][j] % mod) % mod;
ans[(j+k+z) % 3] += z * c[x][j] * c[y][k] % mod;
ans[(j+k+z)%3] %= mod;
}
}
}
for(int j=0;j<3;j++){
if(ok[y][j]){
dp[x][(j+z) % 3] += dp[y][j] + z * c[y][j] % mod;
dp[x][(j+z) % 3] %= mod;
c[x][(j+z)%3] += c[y][j];
ok[x][(j+z) % 3] = true;
}
}
}
}
int main(){
while(~scanf("%d",&n)){
ans[0] = ans[1] = ans[2] = 0;
tot = 0;
for(int i=1;i<=n;i++){
dp[i][0] = dp[i][1] = dp[i][2] = 0;
c[i][1] = c[i][2] = 0;
c[i][0] = 1;
ok[i][0] = true;
ok[i][1] = ok[i][2] = false;
head[i] = 0;
}
for(int i=1;i<n;i++){
scanf("%d%d%lld",&x,&y,&z);
x ++;
y ++;
add(x,y,z);
add(y,x,z);
}
dfs(1,0);
printf("%lld %lld %lld\n",ans[0] * 2 % mod,ans[1] * 2 % mod,ans[2] * 2 % mod);
}
return 0;
}
2019 沈阳网络赛 D Fish eating fruit ( 树形DP)的更多相关文章
- 2019icpc沈阳网络赛 D Fish eating fruit 树形dp
题意 分别算一个树中所有简单路径长度模3为0,1,2的距离和乘2. 分析 记录两个数组, \(dp[i][k]\)为距i模3为k的子节点到i的距离和 \(f[i][k]\)为距i模3为k的子节点的个数 ...
- 2019 沈阳网络赛 Fish eating fruit
这题看了三个月,终于过了,第一次看的时候没学树形DP,想用点分治但是不会 后来学了二次扫描,就有点想法了.... 这东西也真就玄学了吧... #include<iostream> #inc ...
- 2019沈阳网络赛B.Dudu's maze
https://www.cnblogs.com/31415926535x/p/11520088.html 啊,,不在状态啊,,自闭一下午,,都错题,,然后背锅,,,明明这个简单的题,,, 这题题面不容 ...
- [2019沈阳网络赛D题]Dawn-K's water(点分治)
题目链接 题意为求出树上任意点对的距离对3取余的和. 比赛上听到题意就知道是点分治了,但是越写越不对劲,交之前就觉得会T,果不其然T了.修修改改结果队友写了发dp直接就过了Orz. 赛后想了想维护的东 ...
- 【2019沈阳网络赛】G、Special necklace——自闭的物理题
这道题让我差点怀疑自己高考没考过物理 题意中 he measures the resistance of any two endpoints of it, the resistance values ...
- 2019上海网络赛 F. Rhyme scheme 普通dp
Rhyme scheme Problem Describe A rhyme scheme is the pattern of rhymes at the end of each line of a p ...
- 2019 上海网络赛 F Rhyme scheme (字典树DP)
题目:https://nanti.jisuanke.com/t/41414 题意:求长度为n的第k个bell number , 就是第i位的选取范围在 1-(i-1)位的最大值 +1,第一位固定为 ...
- hdu6446 网络赛 Tree and Permutation(树形dp求任意两点距离之和)题解
题意:有一棵n个点的树,点之间用无向边相连.现把这棵树对应一个序列,这个序列任意两点的距离为这两点在树上的距离,显然,这样的序列有n!个,加入这是第i个序列,那么这个序列所提供的贡献值为:第一个点到其 ...
- 2019沈阳网赛树形dp
https://nanti.jisuanke.com/t/41403 2019沈阳网络赛D题 树形dp.一棵树,求任意两个点的距离之和.u-v和v-u算两次.两点之间的距离分为三类,模3等于0,1,2 ...
随机推荐
- STM32 HAL库之串口详细篇
一.基础认识 (一) 并行通信 原理:数据的各个位同时传输 优点:速度快 缺点:占用引脚资源多,通常工作时有多条数据线进行数据传输 8bit数据传输典型连接图: 传输的数据是二进制:11101010, ...
- 【C++】《Effective C++》第五章
第五章 实现 条款26:尽可能延后变量定义式的出现时间 只要定义了一个变量而其类型带有一个构造函数或析构函数,那么 当程序的控制流到达这个变量定义式时,你得承受这个构造成本. 当这个变量离开这个作用域 ...
- 使用 C# 9 的records作为强类型ID - JSON序列化
在本系列的上一篇文章中,我们注意到强类型ID的实体,序列化为 JSON 的时候报错了,就像这样: { "id": { "value": 1 }, "n ...
- LeetCode454. 四数相加 II
题目 给定四个包含整数的数组列表 A , B , C , D ,计算有多少个元组 (i, j, k, l) ,使得 A[i] + B[j] + C[k] + D[l] = 0. 分析 关键是如何想到用 ...
- nmap的理解与利用(初级)
在命令窗口下输入命令等待,可以用回车来查看进度 nmap进行探测之前要把域名通过dns服务器解析为ip地址,我们也可以使用指定的dns服务器进行解析. nmap --dns-servers 主机地址 ...
- 获取html中某些标签的值
一.获取单选按钮radio的值 <!doctype html> <html lang="en"> <head> <meta charset ...
- Mybatis Plus 3.4版本之后分页插件的变化
一.MybatisPlusInterceptor 从Mybatis Plus 3.4.0版本开始,不再使用旧版本的PaginationInterceptor ,而是使用MybatisPlusInter ...
- js 前端词典对象的属性和值读取
通常服务端返回比较奇葩的数据对象,不知道该怎么将这个对象转换为可用实体,想了很久,突发奇想想到了这么个方法. 需求是这样:企业有多个产品,产品有分为很几个种类.服务端有获取产品的接口,和单独获取产品种 ...
- 转 9 jmeter之检查点
9 jmeter之检查点 jmeter有类似loadrunner检查点的功能,就是断言中的响应断言. 1.响应断言(对返回文字结果进行相应的匹配)右击请求-->添加-->断言--> ...
- 二进制GCD
目录 写在前面 具体实现: Code 写在前面 全程抄书 想要进一步提高求 \(\gcd\) 的效率,可以通过不断去除因子 \(2\) 来降低常数,这就是"二进制 \(\gcd\) &quo ...