ds 6.2 expectation

来源:互联网 发布:编程需要哪些基础知识 编辑:程序博客网 时间:2024/06/05 04:03

/***************Problem from :Problem describe :两次dfs   第一次dfs解决   各节点到1的距离  以及各节点的所有直接或者间接的儿子的val之和第二次dfs解决    d表示 节点到父节点的距离 valsum表示val总和  val_i 表示该节点的所有直接或者间接的儿子的val之和 各节点的ans  =  父节点ans -  val_i*d + (valsum-val_i)*d;  此题暴力解会爆 data:2016.12.8****************/#include<iostream>#include<cstdlib>#include<cstdio>#include<algorithm>#include<cmath>#include<map>#include<stack>#include<queue>#include<ctime>#include<cstring>#include<vector>#include<string>#define ll __int64#define inf 0x3f3f3f3f3fusing namespace std;const int maxn = 100005;const int mod = 707063423;struct node{int u, to, w;} v[2*maxn];int first[maxn], next[2*maxn], valsum=0, size[maxn]={0}, dis[maxn], ans[maxn], val[maxn];void addedge(int i, int u){next[i] = first[u];first[u] = i;return ;}int vis[maxn]={0};void dfs(int root, int d){int k;vis[root]=1;dis[root] = d;for(k=first[root]; k!=-1; k=next[k]){int to=v[k].to, temp = v[k].w;if(vis[to]) continue;dfs(to, d+temp);size[root] += size[to];}return;}void dfs_cal(int root){int k;vis[root]=1;for(k=first[root]; k!=-1; k=next[k]){int to=v[k].to, temp = v[k].w;if(vis[to]) continue;ans[to] = ans[root]-size[to]*temp+(valsum-size[to])*temp;dfs_cal(to);}return;}int main(){//  freopen("in.txt","r",stdin);//  freopen("out.txt","w",stdout);int i, n, len=1, x, y, z;scanf("%d", &n);for(i=0; i<n+50; i++) first[i]=-1;for(i=1; i<=n; i++) scanf("%d", &val[i]), size[i]=val[i], valsum+=size[i];for(i=1; i<n; i++){scanf("%d%d%d", &x, &y, &z);v[len].u = x;v[len].to = y;v[len].w = z;addedge (len, x);len++;v[len].u = y;v[len].to = x;v[len].w = z;addedge (len++, y);}dfs(1, 0); for(i=1; i<=n; i++) ans[1] = (ans[1]+(val[i]*dis[i])%mod)%mod, vis[i]=0;dfs_cal(1);int q;scanf("%d", &q);while(q--){scanf("%d", &x);printf("%d\n", ans[x]);}return 0;}



0 0
原创粉丝点击