您的位置:首页 > 其它

CodeForces 543d Road Improvement(巧妙地树形dp)

2015-08-03 21:26 429 查看
//如何求树上任意一点为根的dp值
//将以此点将树划分成两部分,一部分还是原来的子树
//另一部分是此点的父亲往上为子树,这一点的转化很巧妙,一次从上到下的dp即可。
//R[i]记录此点右面子树的乘积,从右到左,其实在最右的时候up[父亲]就已经计算了父亲往上的值了。现在只要记录兄弟即可。

import java.io.*;
import java.util.*;

public class cf {
FastScanner in;
final int INF=0x3fffffff;
final int N=200010;
final long mod = 1000000007;
edge[] e;
int[] head;
int cnt;
long[] dp;
long []L,R;
long[] ans,up;
int temp[]=new int
;

void addedge(int u,int v){
e[cnt]=new edge();
e[cnt].from=u;e[cnt].to=v;
e[cnt].next=head[u];head[u]=cnt++;
}
void DP(int u,int p){
dp[u]=1;
for(int i=head[u];i!=-1;i=e[i].next){
int v=e[i].to;
if(p==v)continue;
DP(v,u);
dp[u]*=(dp[v]+1);
dp[u]%=mod;
}
}
void DFS(int u,int p){//相当于从上到下再dp一次
if(p==-1)up[u]=1;L[0]=1;
int num=0;
for(int i=head[u],j=0;i!=-1;i=e[i].next,j++){
int v=e[i].to;
temp[num++]=v;
if(p==v){
L[j+1]=L[j];
continue;
}
L[j+1]=L[j]*(dp[v]+1)%mod;
}
R[num-1]=up[u];
for(int i=num-1;i>0;i--){
if(temp[i]==p){
R[i-1]=R[i];
continue;
}
R[i-1]=R[i]*(dp[temp[i]]+1)%mod;
}
for(int i=head[u],j=0;i!=-1;i=e[i].next,j++){
int v=e[i].to;
if(v==p)continue;
up[v]=(L[j]*R[j]%mod+1)%mod;
}
for(int i=head[u];i!=-1;i=e[i].next){
int v=e[i].to;
if(v==p)continue;
DFS(v,u);
}
}
void input(){
in = new FastScanner(System.in);
e=new edge[2*N];
head=new int
;
dp=new long
;
L=new long
;
R=new long
;
ans=new long
;
up=new long
;

Arrays.fill(head, -1);
int n=in.nextInt();
cnt=0;
for(int i=2;i<=n;i++){
int v=in.nextInt();
addedge(i,v);
addedge(v,i);
}
DP(1,-1);
DFS(1,-1);
for(int i=1;i<=n;i++)
System.out.print(up[i]*dp[i]%mod+" ");
}
public static void main(String[] args){
new cf().input();
}
}
class edge{
int from,to,next;
}
class FastScanner {
BufferedReader br;
StringTokenizer st;

public FastScanner(File f) {
try {
br = new BufferedReader(new FileReader(f));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}

public FastScanner(InputStream f) {
br = new BufferedReader(new InputStreamReader(f));
}

String next() {
while (st == null || !st.hasMoreTokens()) {
String s = null;
try {
s = br.readLine();
} catch (IOException e) {
e.printStackTrace();
}
if (s == null)
return null;
st = new StringTokenizer(s);
}
return st.nextToken();
}

boolean hasMoreTokens() {
while (st == null || !st.hasMoreTokens()) {
String s = null;
try {
s = br.readLine();
} catch (IOException e) {
e.printStackTrace();
}
if (s == null)
return false;
st = new StringTokenizer(s);
}
return true;
}

int nextInt() {
return Integer.parseInt(next());
}

long nextLong() {
return Long.parseLong(next());
}

double nextDouble() {
return Double.parseDouble(next());
}
String nextLine() {

String str = "";
try {
str = br.readLine();
} catch (IOException e) {
e.printStackTrace();
}
return str;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息