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远程支持 ...
随机推荐
- 【Linux】Linux中的网络命令
dig命令:是常用的域名查询工具,可以用来测试域名系统工作是否正常. 语法: dig(选项)(参数) [root@localhost tmp]# dig http://oa.kingnet.com ; ...
- HDU 1298 T9 字典树+DFS
必须要批评下自己了,首先就是这个题目的迟疑不定,去年做字典树的时候就碰到这个题目了,当时没什么好的想法,就暂时搁置了,其实想法应该有很多,只是居然没想到. 同样都是对单词进行建树,并插入可能值,但是拨 ...
- 吴裕雄--天生自然MySQL学习笔记:MySQL 插入数据
MySQL 表中使用 INSERT INTO SQL语句来插入数据. 可以通过 mysql> 命令提示窗口中向数据表中插入数据,或者通过PHP脚本来插入数据. 以下为向MySQL数据表插入数据通 ...
- Nginx和php交互的两种方式
Unix socket 也叫IPC socket 也就是进程间通信套接字用于同一台主机上的不同进程间交换数据 TCP socket IP socket要利用主机的传输层(tcp),可以用于同一台主机 ...
- Java之创建线程的方式四:使用线程池
import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.c ...
- 分块&莫队模板
最裸的莫队:https://www.luogu.org/problemnew/show/P1494 #include<bits/stdc++.h> #define ll long long ...
- Java 面向对象概述原理: 多态、Object类,转型(8)
Java 面向对象概述原理: 多态.Object类,转型(8) http://docs.oracle.com/javase/tutorial/java/IandI/override.html Java ...
- share团队冲刺9
团队冲刺第九天 昨天:完善代码 今天:修改代码中的问题,提高兼容性 问题:无
- 最大子矩阵和(二维矩阵转一维DP)
题目描述 蒜头君拿到了一个矩阵,他想知道其中的最大非空子矩阵和是多少. 输入格式 第一行输入两个整数 n,m代表这个矩阵的行数和列数.接下来n行,每行m个整数 ai1,ai2,ai3⋯aim.(1≤m ...
- ajax上传图片到服务器简单操作
前端: 通过Ajax方式上传文件,使用FormData进行Ajax请求.上传文件或图片时,要求的格式为enctype ="multipart/form-data"(以二进制格式上传 ...