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 ...
随机推荐
- nacos服务注册与发现原理解析
前言:nacos 玩过微服务的想必不会陌生,它是阿里对于springcloud孵化出来的产品,用来完成服务之间的注册发现和配置中心,其核心作用我就不废话了 大致流程:每个服务都会有一个nacos cl ...
- 简单TCP服务器和TCP客户端源码(Golang)
以下代码为服务端,非最终版代码,服务端可以接受多个客户端的请求,且所有消息会显示在服务端上,服务端无法发送消息: package main import ( "fmt" " ...
- Flutter 基础组件:状态管理
前言 一个永恒的主题,"状态(State)管理",无论是在React/Vue(两者都是支持响应式编程的Web开发框架)还是Flutter中,他们讨论的问题和解决的思想都是一致的. ...
- SpringBoot整合Shiro完成验证码校验
SpringBoot整合Shiro完成验证码校验 上一篇:SpringBoot整合Shiro使用Redis作为缓存 首先编写生成验证码的工具类 package club.qy.datao.utils; ...
- logback为不同的包或类指定输出日志文件
对日志分割的常见需求是,需要按不同的等级进行输出,这个的配置方式类似如下,在appender节点内添加内容 <appender name="FILE-INFO" class= ...
- JavaScript入门-函数function(二)
JavaScript入门-函数function(二) 递归函数 什么是递归函数? 递归简单理解就是,在函数体里,调用自己. //我们在求一个10的阶乘的时候,可能会这么做 //写一个循环 var to ...
- Java开发手册之安全规约
1.用户敏感数据禁止直接展示,必须对展示数据进行脱敏.例如手机号.银行卡号等,中间要用*隐藏. 2.发贴.评论.发送即时消息等用户生成内容的场景必须实现防刷.文本内容违禁词过滤等风控策略,一般是用验证 ...
- SDUST数据结构 - chap4 串
函数题: 6-1 查找子串: 裁判测试程序样例: #include <stdio.h> #define MAXS 30 char *search(char *s, char *t); vo ...
- openshift 3.11安装部署
openshift 3.11 安装部署 openshift安装部署 1 环境准备(所有节点) openshift 版本 v3.11 1.1 机器环境 ip cpu mem hostname OSsys ...
- JS中常用的工具类
一.日期工具类 /** * 日期时间工具类 * @type {{dateFormat}} */ var DateTime = function () { var patterns = { PATTER ...