码迷,mamicode.com
首页 > 其他好文 > 详细

Codeforces 543D Road Improvement 树形dp

时间:2015-05-09 22:08:20      阅读:156      评论:0      收藏:0      [点我收藏+]

标签:

题目链接:点击打开链接

题意:

给定n个点的树

问:

对于以i为根时,把树边黑白染色,使得任意点走到根的路径上不超过一条黑边,输出染色的方案数(mod 1e9+7)

思路:

显然i点的方案数 = i为根的子树的方案数 * 不包括i为根的子树的部分的方案数

首先以i为根的子树求一个方案数down[i]:for all son vj  of i, down[i] = multiply down[j]

求不包括i子树的时候为了避免除法,对儿子的方案数求一个前缀积和后缀积即可

避免了使用逆元

#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <vector>
#include <string>
#include <time.h>
#include <math.h>
#include <queue>
#include <stack>
#include <set>
#include <map>
const double eps = 1e-8;
const double pi = acos(-1.0);
template <class T>
inline bool rd(T &ret) {
	char c; int sgn;
	if (c = getchar(), c == EOF) return 0;
	while (c != '-' && (c<'0' || c>'9')) c = getchar();
	sgn = (c == '-') ? -1 : 1;
	ret = (c == '-') ? 0 : (c - '0');
	while (c = getchar(), c >= '0'&&c <= '9') ret = ret * 10 + (c - '0');
	ret *= sgn;
	return 1;
}
template <class T>
inline void pt(T x) {
	if (x <0) { putchar('-'); x = -x; }
	if (x>9) pt(x / 10);
	putchar(x % 10 + '0');
}
using namespace std;
typedef long long ll;
const int N = 200100;
const int mod = 1e9 + 7;
int n;
vector<int>G[N];
vector<ll>D[N], P[N];
ll down[N], up[N];
ll go[N];
void mul(ll &x, ll y){
	x *= y;
	x %= mod;
}
void dfs_down(int u, int fa){
	down[u] = 1;
	for (int i = 0; i < G[u].size(); i++){
		int v = G[u][i]; if (v == fa){
			D[u].push_back(1); P[u].push_back(1); continue;
		}
		dfs_down(v, u);
		mul(down[u], down[v] + 1);
		D[u].push_back(down[v] + 1);
		P[u].push_back(down[v] + 1);
	}
	for (int i = 1; i < D[u].size(); i++)	mul(D[u][i], D[u][i - 1]);
	for (int i = (int)P[u].size() - 2; i >= 0; i--)	
		mul(P[u][i], P[u][i + 1]);
}
void dfs_up(int u, int fa, ll way){
	up[u] = way;
	for (int i = 0; i < G[u].size(); i++){
		int v = G[u][i]; if (v == fa)continue;
		ll tmp = way;
		if (i && i < (int)D[u].size()) mul(tmp, D[u][i - 1]);
		if (i + 1 < P[u].size())
			mul(tmp, P[u][i + 1]);
		dfs_up(v, u, tmp + 1);
	}
}
int main(){
	rd(n);
	for (int i = 2, x; i <= n; i++){
		rd(x); G[x].push_back(i); G[i].push_back(x);
	}
	dfs_down(1, 1);
	dfs_up(1, 1, 1);
	for (int i = 1; i <= n; i++)pt(down[i] * up[i] % mod), putchar(' ');
	return 0;
}


Codeforces 543D Road Improvement 树形dp

标签:

原文地址:http://blog.csdn.net/qq574857122/article/details/45604661

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!