jzoj 3844. 统计损失(count) (Standard IO)

Description
SJY有一天被LLT紧急召去计算一些可能的损失。LLT元首管理的SHB国的交通形成了一棵树,现在将会出现一颗陨石砸在SHB国中,并且陨石砸毁的必定是SHB国构成的交通树上的一条路径。SHB国的损失可表示为被砸毁的路径上的所有城市价值之积。现在还暂时无法确定陨石的掉落路线,所以LLT元首希望SJY能够告诉他SHB国在受到每一种砸毁方式后会受到的损失之和模10086之后的值。注意:单独一个节点也被认为是合法的路径。

Input
第1行一个数n,表示城市数。
第2行n个数,第i个数表示第i个城市的价值。
第3到n+1行,每行两个数u,v,表示城市u,v之间有一条道路。

Output
包含一个数,表示SHB国将受到的损失之和。

Sample Input
5
7 6 6 1 1
1 2
2 3
2 4
1 5

Sample Output
778

Data Constraint
对于20%的数据,n<=100;
对于50%的数据,n<=3000;
对于100%的数据,n<=100000。

//written by zzy

题目大意:

求一个树的所有路径积(路径上的所有点的权值之积)

题解:

树形dp,设 f [ x ] f[x] f[x]为以 x x x为根的子树的到 x x x的所有路径积之和(所有直链到x的路径积),
考虑如何转移和求出答案
发现转移很简单, f [ x ] = s u m w [ x ] ∗ f [ s o n ] f[x]=sum{ w[x]*f[son]} f[x]=sumw[x]f[son]
f [ x ] f[x] f[x]不能算上折链(“V”形路径)的路径积,(因为 f [ x ] f[x] f[x]要层层传上去,就不能表示两点之间的路径积了)
所以答案要再另外加上所有折链的路径积,
考虑如何求,
其实折链可以看成两条直链(从一个节点到 x x x再到另一个节点),
子树 x x x到子树 y y y的所有路径积 ( x , y ) (x,y) (x,y)等于 f [ x ] ∗ w [ l c a ( x , y ) ] ∗ f [ y ] f[x]*w[lca(x,y)]*f[y] f[x]w[lca(x,y)]f[y]
但不能两两计算 ( x , y ) (x,y) (x,y),(时间复杂度会退化)
可以考虑当遍历完一个子树后将其加入 f [ x ] f[x] f[x]中,
累记起来(相当于不断合并子树,边合并边更新答案)

#include<iostream> 
#include<cstdio>
#include<algorithm>
#include<cstring>
#define N 100005
#define Mod 10086
using namespace std;

int i,j,n,m,l,x;
long long ans;
int w[N],f[N];
bool vis[N];

int list[N],v[2*N],next[2*N];

void add(int x) {
	next[++l]=list[x];
	list[x]=l;
}

void dfs(int x) {
	f[x]=w[x];
	for (int t=list[x],y=v[t];t;t=next[t],y=v[t]) 
     if (!vis[y]) {
     	vis[y]=true; dfs(y);
     	ans=(ans+(f[x]*f[y])%Mod)%Mod;//更新答案
     	f[x]=(f[x]+(f[y]*w[x])%Mod)%Mod;//合并子树
     }
}  

int main()
{
	scanf("%d",&n);
	for (i=1;i<=n;i++) { 
	 scanf("%d",&w[i]);
	 ans+=w[i];
    }
	for (i=1;i<=n-1;i++) {
		scanf("%d%d",&x,&v[i*2-1]); add(x);
		v[i*2]=x; add(v[i*2-1]); 
	}
	vis[1]=true;
	dfs(1);
	printf("%d",ans);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值