首页 > 代码库 > 统计损失

统计损失

题目描述

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

输入

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

输出

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

样例输入

5
7 6 6 1 1
1 2
2 3
2 4
1 5

样例输出

778

提示

 

【数据规模和约定】

n<=100;

n<=3000;

n<=100000

题意

给你一棵树,求树上任意一条路径的节点的积的和。

 

题解

(1)头尾的lca等于头或尾

        f[i]=f[v[i]]∗a[i],f[i]表示以i节点为头(尾)的路径的乘积之和

(2)头尾的lca不为头或尾,即倒“V”型

        我们发现若两点(u,v)的lca为i ,那么可以划分为u到i的直线*v到i的直线。 

        那么lca为i的路径乘积之和为

        对于搜到的每一个子节点,ans:=ans+sum*f[v];sum:=sum+f[v]*a[u];

技术分享
const oo=10086;maxn=200010;var n,i,u,v,tot,ans:longint;    a,vet,next,head,f:array[0..maxn] of longint;procedure add(u,v:longint);begin  inc(tot);  vet[tot]:=v;  next[tot]:=head[u];  head[u]:=tot;  inc(tot);  vet[tot]:=u;  next[tot]:=head[v];  head[v]:=tot;end;procedure dfs(u,pre:longint);var e,v:longint;begin  e:=head[u];  while e<>0 do  begin    v:=vet[e];    if v<>pre then    begin      dfs(v,u);      ans:=(ans+(f[u]-a[u]+oo)*f[v]) mod oo;      f[u]:=(f[u]+f[v]*a[u]) mod oo;    end;    e:=next[e];  end;  ans:=(ans+f[u]) mod oo;end;beginread(n);for i:=1 to n dobegin  read(a[i]);  f[i]:=a[i];end;for i:=1 to n-1 dobegin  read(u,v);  add(u,v);end;dfs(1,0);write(ans);end.
View Code

 

 

      

统计损失