P5007 但模数的疑惑

· · 题解

省流:\bmod\ 10^8+7

现有题解好像都没有认真讲转移式怎么来的,我来写一下。

显然设 f_u 为子树内价值和,w_uu 的点权,由于需要知道集合数才能转移,再设 g_u 为子树内集合数。

- 已考虑的子树和目前子树内所有集合组合:$f_u\times g_v$。 - 已考虑的子树内所有集合和目前子树组合:$g_u\times f_v$。 - 不取目前子树集合:$f_u$。 - 只取目前子树集合:$f_v$。 - 综上:$f_u\to f_u\times g_v+g_u\times f_v+f_u+f_v$。 $g_u$ 的转移: - 已考虑的子树内所有集合和目前子树集合组合 $g_u\times g_v$。 - 不取目前子树集合:$g_u$。 - 只取目前子树集合:$g_v$。 - 综上:$g_u\to g_u\times g_v+g_u+g_v$。 注意到只取 $u$ 也是一种情况,在最后令 $f_u\to f_u+w_u,g_u\to g_u+1$ 即可。 答案显然为 $f_1$。 代码: ```cpp #include<bits/stdc++.h> using namespace std; #define ll long long const int N=1e6+5,mod=1e9+7; int n,t,u,v; ll f[N],g[N],w[N]; vector<int> G[N]; void dfs(int u,int fa){ for(int v:G[u]){ if(v==fa) continue; dfs(v,u); f[u]=(f[u]*g[v]+f[v]*g[u]+f[u]+f[v])%mod; g[u]=(g[u]*g[v]+g[u]+g[v])%mod; } (f[u]+=w[u])%mod; g[u]++; } int main(){ cin>>n>>t; for(int i=1;i<n;i++){ cin>>u>>v; G[u].push_back(v); G[v].push_back(u); } for(int i=1;i<=n;i++) w[i]=t*(i-1)+1; dfs(1,1); cout<<f[1]; return 0; } ```