[HDU4625] JZPTREE+[国家集训队] Crash 的文明世界 题解

老师发福利,放了两道一毛一样的题。


考虑无视战术,直接化简:

\[\sum_{v=1}^ndis(u,v)^k=\sum_{v=1}^n\sum_{i=0}^k\begin{Bmatrix}k\\i\end{Bmatrix}dis(u,v)^{\underline i} \]

\[=\sum_{i=0}^k\begin{Bmatrix}k\\i\end{Bmatrix}\sum_{v=1}^ndis(u,v)^{\underline i} \]

\[=\sum_{i=0}^k\begin{Bmatrix}k\\i\end{Bmatrix}\sum_{v=1}^ni!\binom{dis(u,v)}i \]

\[=\sum_{i=0}^k\begin{Bmatrix}k\\i\end{Bmatrix}i!\sum_{v=1}^n\binom{dis(u,v)}i \]

\[=\sum_{i=0}^k\begin{Bmatrix}k\\i\end{Bmatrix}i!\sum_{v=1}^n\binom{dis(u,v)-1}i+\binom{dis(u,v)-1}{i-1} \]

为什么要进行最后一步分解呢?这和接下来的推导有关系。

实际上推到这里已经不用再推了,我们只需要能求出 \(f_{u,i}=\sum\limits_{v=1}^n\binom{dis(u,v)}i\) 就可以了。考虑换根 \(dp\)

首先显然有:

\[f_{u,0}=1+\sum_{v\in son(u)}f_{v,0} \]

对于 \(i>0\) 的情况,我们可以使用最后一步的推导。考虑最后一步 \(dis(u,v)-1\) 相当于是把问题转化到了儿子上,即:

\[f_{u,i}=\sum_{v\in son(u)}f_{v,i-1}+f_{v,i} \]

换根 \(dp\),时间复杂度 \(O(nk)\)

#include<bits/stdc++.h>
using namespace std;
const int N=155,M=50005,p=10007;
int str[N][N],f[M][N],g[M][N],ans;
vector<int>ve[M];int n,k,l,nw,aa,bb,q;
void dfs1(int x,int fa){
    for(auto y:ve[x]){
        if(y==fa) continue;dfs1(y,x);
        f[x][0]=(f[x][0]+f[y][0])%p;
        for(int i=1;i<=k;i++)
            f[x][i]=(f[x][i]+f[y][i]+f[y][i-1])%p;
    }f[x][0]++;
}void dfs2(int x,int fa){
    if(x!=1){
        for(int i=1;i<=k;i++){
            g[x][i]+=g[fa][i]+g[fa][i-1]+f[fa][i];
            g[x][i]+=f[fa][i-1]-f[x][i]-2*f[x][i-1];
            if(i>1) g[x][i]-=f[x][i-2];g[x][i]%=p;
        }g[x][0]=(g[fa][0]+f[fa][0]-f[x][0]+p)%p;
    }for(auto y:ve[x])
        if(y!=fa) dfs2(y,x);
}int main(){
    ios::sync_with_stdio(0);
    cin.tie(0),cout.tie(0);
    cin>>n>>k>>l>>nw>>aa>>bb>>q,str[0][0]=1;
    for(int i=1;i<n;i++){
        nw=(nw*aa+bb)%q;
        int tmp=(i<l?i:l);
        int x=i-nw%tmp,y=i+1;
        ve[x].push_back(y);
        ve[y].push_back(x);
    }for(int i=1;i<=k;i++) for(int j=1;j<=i;j++)
        str[i][j]=(str[i-1][j-1]+str[i-1][j]*j)%p;
    dfs1(1,0),dfs2(1,0);
    for(int j=1;j<=n;j++,ans=0){
        for(int i=0,jc=1;i<=k;i++,jc=jc*i%p){
            int now=str[k][i]*jc%p;
            ans=(ans+now*(f[j][i]+g[j][i]))%p;
        }cout<<(ans+p)%p<<"\n";
    }return 0;
}
posted @   长安一片月_22  阅读(4)  评论(0编辑  收藏  举报
编辑推荐:
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
点击右上角即可分享
微信分享提示