The topic probably said to a tree, the edge of the tree is damaged, to repair some side, after the repair to meet each point to the root of the path of up to only one bad side, and now to the root of the various points for the repair of the side of the scheme number, the result of the model 1000000007.
It is not difficult to think of this problem and HDU2196 is a type of tree DP, because they have to ask each point of the answer. Then the solution is not difficult to think:
- Dp0[u] Indicates the number of scenarios that only consider the subtree with the U node as the root
- Dp1[u] Represents the U node going up, upside down, with its father as the root of that part of the program number
With the results of these two parts, the answer to each point U is dp0[u]* (dp1[u]+1). The two parts of the law as follows, drawing a better think:
- First find out the DP0, this transfer is: Dp0[u]=∏ (dp0[v]+1) (V is the child of U), that is, the total number of times each child is the root of the sub-tree, and the total number of each child is added to a father to the child between the side of the repair, the child's child tree side of all repair situation.
- Then find out DP1, transfer: Dp1[v],u is the father of V, dp1[v]=dp0[u]/dp0[v]* (dp1[u]+1).
- Now that's the problem, ask Dp0[u]/dp0[v], notice that the result modulo 1000000007 is a prime number, and at first I used the multiplication inverse of WA, because although 1000000007 is prime, but the multiples of 1000000007 are not with 1000000007 coprime, Modulo 1000000007 turns out to be 0, so it's a problem!
- Originally I would like to use a line segment tree to do, but teammates remind that can be discussed, if there is no direct inverse with 1000000007 coprime, there are more than two not with 1000000007 coprime number that result is 0, one word .... I'm not going to say much.
1#include <cstdio>2#include <cstring>3#include <algorithm>4 using namespacestd;5 #defineMAXN 2222226 structedge{7 intV,next;8}edge[maxn<<1];9 intNE,HEAD[MAXN];Ten voidAddedge (intUintv) { OneEdge[ne].v=v; edge[ne].next=Head[u]; Ahead[u]=ne++; - } - Long Longd[2][MAXN]; the Long LongIneLong Longa) { - Long Longres=1; - intn=1000000007-2; - while(n) { + if(n&1){ -res*=A; +res%=1000000007; A } ata*=A; -a%=1000000007; -n>>=1; - } - returnRes; - } in voidDp0 (intUintFA) { - Long Longres=1; to for(intI=head[u]; i!=-1; I=Edge[i].next) { + intv=edge[i].v; - if(V==FA)Continue; the dp0 (v,u); *res*=d[0][v]+1; $res%=1000000007;Panax Notoginseng } -d[0][u]=Res; the } + voidDP1 (intUintFA) { A intCnt=0; the Long Longtot=1; + for(intI=head[u]; i!=-1; I=Edge[i].next) { - intv=edge[i].v; $ if(V==FA)Continue; $ if((d[0][v]+1)%1000000007==0) ++CNT; - Else{ -tot*=d[0][v]+1; thetot%=1000000007; - }Wuyi } the for(intI=head[u]; i!=-1; I=Edge[i].next) { - intv=edge[i].v; Wu if(V==FA)Continue; - if(CNT) { About if((d[0][v]+1)%1000000007==0&& cnt==1){ $d[1][v]=tot; -}Elsed[1][v]=0; -}Else{ -d[1][v]=d[0][u]*ine ((d[0][v]+1)%1000000007); Ad[1][v]%=1000000007; + } thed[1][v]*=d[1][u]+1; -d[1][v]%=1000000007; $ DP1 (v,u); the } the } the intMain () { thememset (head,-1,sizeof(head)); - intN,a; inscanf"%d",&n); the for(intI=2; i<=n; ++i) { thescanf"%d",&a); About Addedge (a,i); the Addedge (i,a); the } theDp0 (1,1); +DP1 (1,1); - for(intI=1; i<=n; ++i) { theprintf"%lld"-D:0][i]* (d[1][i]+1)%1000000007);Bayi } the return 0; the}
Codeforces 543D Road Improvement (tree-shaped dp+ multiplication inverse)