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远程支持 ...
随机推荐
- part12 非核心代码异步加载
router文件中的 index component: ()=> import(‘path’) // 这样 访问一个页面 就只请求这个页面的js逻辑 //当app很小的的时候不需要做异步拆分 / ...
- 使用Object类为实例定义方法和属性
1.1 可以使用 Object 类直接定义个实例,并且为该对象赋属性和方法,例如: var person_1 = { nickName:"xiaowu", age:28, show ...
- CodeForces 1000A Codehorses T-shirts(STL map、思维)
https://codeforces.com/problemset/problem/1000/A 题意: 有n个人,给出每个人的衣服的尺码,现在,将这n件衣服的尺码换成另外的n种尺码,如果有尺码一样的 ...
- 吴裕雄--天生自然 JAVASCRIPT开发学习: 表单
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <script> ...
- android stutio 添加依赖
添加依赖有 3种方法: 1 :copy jar 包到libs目录 ,add to library 2: copy aar 文件到libs ,gradle 文件 android 节点添加 repo ...
- Eclipse打开,出现Initializing Java Tooling “has encountered a problem错误,而且鼠标悬停在没有导包的类上面不会出现import信息。
问题1:打开eclipse,出现了Initializing Java Tooling “has encountered a problem,点开详细信息,报的是空指针异常. 问题2:鼠标悬停在没有导包 ...
- 23. docker 数据持久化 bind mounting
1. bind mounting 和 data volume 的区别 data volume 需要在 Dockerfile 定义 Volume bind mounting 只需要 -v 指明 容器外部 ...
- 注意力机制和Seq2seq模型
注意力机制 在"编码器-解码器(seq2seq)"⼀节⾥,解码器在各个时间步依赖相同的背景变量(context vector)来获取输⼊序列信息.当编码器为循环神经⽹络时,背景变量 ...
- h3c 瘦ap无法上线解决办法(WA4320i-ACN)
瘦ap无法上线的原因主要有两个:1.无法获取IP地址 2 .版本 胖ap转瘦ap: 1.使用网线+web对ap进行管理,默认IP地址为:192.168.0.50,用户名:admin 密码:h3capa ...
- 67)vector的begin() end() 和 front() back()的区别 rbegin() rend()
1) ·············· 2)`````````v1.begin() 和v1.end() 是作为迭代器v1的 第一个位置 和 最后一个元素的下一个位置. `````````````v1. ...