【DP】 Codeforces Round #302 (Div. 1) D - Road Improvement

来源:互联网 发布:网络红猫红小胖 编辑:程序博客网 时间:2024/04/28 04:21

简单的树形dp,转移就是dp[i] = dp[i] * (dp[j]+1)其中j是i的子节点,叶节点为1.但是换根的时候注意不能用逆元,因为方案数不可能为0,但是取模的时候却有可能出现0,但是换根的时候用逆元就错了。。。换根的时候只能再开个邻接表求了。。。。

#include <iostream>#include <queue>#include <stack>#include <map>#include <set>#include <bitset>#include <cstdio>#include <algorithm>#include <cstring>#include <climits>#include <cstdlib>#include <math.h>#include <time.h>#define maxn 200005#define maxm 400005#define eps 1e-7#define mod 1000000007#define INF 0x3f3f3f3f#define PI (acos(-1.0))#define lowbit(x) (x&(-x))#define mp make_pair#define ls o<<1#define rs o<<1 | 1#define lson o<<1, L, mid #define rson o<<1 | 1, mid+1, R#define pii pair<int, int>#pragma comment(linker, "/STACK:16777216")typedef long long LL;typedef unsigned long long ULL;//typedef int LL;using namespace std;LL qpow(LL a, LL b){LL res=1,base=a;while(b){if(b%2)res=res*base;base=base*base;b/=2;}return res;}LL powmod(LL a, LL b){LL res=1,base=a;while(b){if(b%2)res=res*base%mod;base=base*base%mod;b/=2;}return res;}//headvector<LL> pre[maxn], suf[maxn];vector<int> g[maxn];LL res[maxn];LL dp[maxn];int n;void read(){int x;scanf("%d", &n);for(int i = 2; i <= n; i++) {scanf("%d", &x);g[x].push_back(i);}}void dfs(int u){int size = g[u].size();dp[u] = 1;for(int i = 0; i < size; i++) {dfs(g[u][i]);dp[u] = dp[u] * (dp[g[u][i]] + 1) % mod;}LL res1 = 1, res2 = 1;for(int i = 0; i < size; i++) {res1 = res1 * (dp[g[u][i]] + 1) % mod;res2 = res2 * (dp[g[u][size - i - 1]] + 1) % mod;pre[u].push_back(res1);suf[u].push_back(res2);}reverse(suf[u].begin(), suf[u].end());}void DFS(int u, LL pa){int size = g[u].size();res[u] = (pa + 1) * dp[u] % mod;for(int i = 0; i < size; i++) {LL t = (pa + 1);if(i) t = t * pre[u][i-1] % mod;if(i != size - 1) t = t * suf[u][i+1] % mod;DFS(g[u][i], t);}}void work(){dfs(1);DFS(1, 0);for(int i = 1; i <= n; i++) printf("%lld%c", res[i], i == n ? '\n' : ' ');}int main(){read();work();return 0;}


0 0
原创粉丝点击