D. Fish eating fruit
题:https://nanti.jisuanke.com/t/41403
题意:求任意俩点之间距离之和模3后的三个结果的总数(原距离之和)
第一种做法:
树形dp
#include<bits/stdc++.h>
using namespace std;
#define pb push_back
typedef long long ll;
const int M=1e4+;
const int mod=1e9+;
struct node{
int v;
ll w;
};
ll C[M][],S[M][],ans[M];
//C[i][j]:表示以i为根,然后路径消耗取模后为j的路径数
//S[i][j]:表示以i为根,路径消耗取模后为j的路径总消耗
vector<node>e[M];;
void dfs(int u,int f,ll pre){
C[u][]=C[u][]=C[u][]=;
S[u][]=S[u][]=S[u][]=;
int len=e[u].size();
for(int i=;i<e[u].size();i++){
int v=e[u][i].v;
if(v==f)
continue;
dfs(v,u,e[u][i].w);
//算跨越跟节点的贡献
for(int p=;p<;p++){
for(int j=;j<;j++)
for(int k=;k<;k++)
if(p==(j+k)%)
ans[p]=(ans[p]+S[u][j]*C[v][k]%mod+C[u][j]*S[v][k]%mod)%mod;
}
for(int j=;j<;j++){
C[u][j]=(C[u][j]+C[v][j])%mod;
S[u][j]=(S[u][j]+S[v][j])%mod;
} } for(int i=;i<;i++)//算以u为跟对答案的贡献,就直接算u的每一个子树的贡献 ans[i]=(ans[i]+S[u][i])%mod;
ll c[],s[];
memset(c,0ll,sizeof(c));
memset(s,0ll,sizeof(s));
for(int i=;i<;i++){
int t=(i-pre%+)%;
c[i]=(c[i]+C[u][t])%mod;
s[i]=(s[i]+(S[u][t]+C[u][t]*pre%mod)%mod)%mod;
}
if(f!=)
c[pre%]=(c[pre%]+1ll)%mod,s[pre%]=(s[pre%]+pre)%mod;
for(int i=;i<;i++)
C[u][i]=c[i],S[u][i]=s[i];
}
int main(){
int n;
while(~scanf("%d",&n)){
for(int i=;i<=n;i++)
e[i].clear();
memset(S,,sizeof(S));
memset(C,,sizeof(C));
for(int i=;i<n;i++){
int u,v;
ll w;
for(int i=;i<;i++)
ans[i]=0ll;
scanf("%d%d%lld",&u,&v,&w);
u++,v++;
e[u].pb(node{v,w});
e[v].pb(node{u,w});
}
dfs(,,);
printf("%lld %lld %lld\n",ans[]*2ll%mod,ans[]*2ll%mod,ans[]*2ll%mod); }
return ;;
}
第二种做法:
点分治
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int M=2e4+;
const ll mod=1e9+;
struct node{
int v,nextt;
ll w;
}e[M<<];
ll sum[],disnum[],dissum[];
int head[M],vis[M],sz[M],maxv[M],tot,n,maxx,root;
void addedge(int u,int v,ll w){
e[tot].v=v;
e[tot].nextt=head[u];
e[tot].w=w;
head[u]=tot++;
}
void dfssz(int u,int f){
maxv[u]=;
sz[u]=;
for(int i=head[u];~i;i=e[i].nextt){
int v=e[i].v;
if(v==f||vis[v])
continue;
dfssz(v,u);
sz[u]+=sz[v];
maxv[u]=max(maxv[u],sz[v]);
}
}
void dfsroot(int r,int u,int f){
maxv[u]=max(maxv[u],sz[r]-sz[u]);
if(maxx>maxv[u]){
maxx=maxv[u];
root=u;
}
for(int i=head[u];~i;i=e[i].nextt){
int v=e[i].v;
if(v==f||vis[v])
continue;
dfsroot(r,v,u);
}
}
void dfsdis(int u,int f,ll d){
// if(f!=-1&&d!=0)
disnum[d%]++;
disnum[d%]%=mod;
dissum[d%]+=d;
dissum[d%]%=mod;
for(int i=head[u];~i;i=e[i].nextt){
int v=e[i].v;
if(vis[v]||v==f)
continue;
dfsdis(v,u,(d+e[i].w)%mod);
}
}
void cal(int u,ll d,int flag){
for(int i=;i<;i++)
dissum[i]=disnum[i]=; dfsdis(u,-,d);
for(int i=;i<;i++)
for(int j=;j<;j++){
int t=(i+j)%;
sum[t]=(sum[t]+flag*((disnum[i]*dissum[j]%mod+disnum[j]*dissum[i]%mod)%mod)%mod+mod)%mod;
}
}
void solve(int u){
maxx=n;
dfssz(u,-);
dfsroot(u,u,-);
cal(root,0ll,);//+
vis[root]=;
for(int i=head[root];~i;i=e[i].nextt){
int v=e[i].v;
if(vis[v])
continue;
cal(v,e[i].w,-);
solve(v);
}
}
int main(){
while(~scanf("%d",&n)){
sum[]=sum[]=sum[]=;
tot=;
for(int i=;i<=n;i++)
head[i]=-,vis[i]=;;
for(int i=;i<n;i++){
int u,v;
ll w;
scanf("%d%d%lld",&u,&v,&w);
u++,v++;
addedge(u,v,w);
addedge(v,u,w);
}
solve();
printf("%lld %lld %lld\n",sum[],sum[],sum[]);
}
return ;
}
D. Fish eating fruit的更多相关文章
- Fish eating fruit 沈阳网络赛(树形dp)
Fish eating fruit \[ Time Limit: 1000 ms \quad Memory Limit: 262144 kB \] 题意 大体的题意就是给出一棵树,求每一对点之间的距离 ...
- 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 ...
- The Preliminary Contest for ICPC Asia Shenyang 2019 D. Fish eating fruit(树形dp)
题意:求一棵树上所有路径和模3分别为0 1 2 的权值的和 思路:树形dp 增加一个记录儿子节点满足条件的个数的数组 不要放在一起dp不然答案跟新会有问题 #include <bits/stdc ...
- 2019 沈阳网络赛 D Fish eating fruit ( 树形DP)
题目传送门 题意:求一颗树中所有点对(a,b)的路径长度,路径长度按照模3之后的值进行分类,最后分别求每一类的和 分析:树形DP \(dp[i][j]\) 表示以 i 为根的子树中,所有子节点到 i ...
- 2019ICPC沈阳网络赛-D-Fish eating fruit(树上DP, 换根, 点分治)
链接: https://nanti.jisuanke.com/t/41403 题意: State Z is a underwater kingdom of the Atlantic Ocean. Th ...
- The Preliminary Contest for ICPC Asia Shenyang 2019
传送门 B. Dudu's maze 题意: 是什么鬼东西???我读题可以读半小时QAQ 给出一张无向图,一个人在里面收集糖果,每个点都有一个糖果,特殊点除外.当他第一次进入特殊点时,会随机往一条边走 ...
- SpringRMI远程方法调用
Spring为各种远程访问技术的集成提供了工具类. 该小段引用自 http://www.open-open.com/lib/view/open1408957290478.html Spring远程支持 ...
- SpringRMI远程方法调用【原】
Spring为各种远程访问技术的集成提供了工具类. 该小段引用自 http://www.open-open.com/lib/view/open1408957290478.html Spring远程支持 ...
随机推荐
- 一个例子搞清楚Java程序执行顺序
当我们new一个GirlFriend时,我们都做了什么? 一个例子搞懂Java程序运行顺序 public class Girl { Person person = new Person("G ...
- JAVA函数库
1. 文件相关 1.1 判断目录是否存在 public static boolean dictionaryExist(String path) { File file = new File(path) ...
- POJ 1401:Factorial 求一个数阶乘的末尾0的个数
Factorial Time Limit: 1500MS Memory Limit: 65536K Total Submissions: 15137 Accepted: 9349 Descri ...
- Python连接Oracle问题
Python连接Oracle问题 1.pip install cx_oracle 2.会出现乱码问题: 方法一:配置环境变量 export NLS_LANG="SIMPLIF ...
- 零基础程序员入门Linux系统 !如何快速恢复系统?
新手在学习Linux系统的时候,难免会遇到命令输错,或系统出错的难题.那么如何快速解决呢?本文就先给你一个后悔药,让你快速备份并恢复Linux系统.本文将以Ubuntu为例,在这之前,你需要一台服务器 ...
- 题解 P1082 【同余方程】
题目 这里给出非递归的 exgcd 做法 [基础] ( 只需要非递归的同学麻烦跳过 ) 由于欧几里德算法 ( 又名辗转相除法 ) 可以帮助我们求出最大公约数,并且提出对于 \(\forall a,b\ ...
- SQLServer多条件查询技巧
2019-10-15 13:31:04 在实际项目开发中,有很多页面都会出现多条件查询功能,类似于这种情况: 牵扯到数据就少不了数据库了.这么多条件的查询,如果要用常规的if else来写判断逻辑的 ...
- 吴裕雄--天生自然MySQL学习笔记:MySQL 元数据
你可能想知道MySQL以下三种信息: 查询结果信息: SELECT, UPDATE 或 DELETE语句影响的记录数. 数据库和数据表的信息: 包含了数据库及数据表的结构信息. MySQL服务器信息: ...
- SQL基础教程(第2版)第6章 函数、谓词、CASE表达式:6-1 函数
6-1 各种各样的函数 ● 函数的种类很多,无需全都记住,只需要记住具有代表性的函数就可以了,其他的可以在使用时再进行查询. ■函数的种类所谓函数,就是输入某一值得到相应输出结果的功能,输入值称为参数 ...
- E - Tokitsukaze and Duel CodeForces - 1190C (博弈 + 窗体移动)
"Duel!" Betting on the lovely princess Claris, the duel between Tokitsukaze and Quailty ha ...