传送门


思路

又见到这个\(k\)次方啦!按照套路,我们将它搞成斯特林数:

\[ans_x=\sum_{i=0}^k i!S(k,i)\sum_y {dis(x,y) \choose i}
\]

前面可以枚举,考虑后面那东西怎么求。

我们不知道为什么但就是考虑DP:设:

\[dn_{x,t}=\sum_{y\in x} {dis(x,y) \choose t}\\
up_{x,t}=\sum_{y\notin x} {dis(x,y) \choose t}
\]

其中\(y\in x\)表示\(y\)在\(x\)的子树内。

显然\(dn\)比较好求,我们先搞\(dn\)。

\[\begin{align*}
dn_{x,t}&=\sum_{y\in x} {dis(x,y) \choose t}\\
&=[t=0]+\sum_v \sum_{y\in v} {dis(v,y)+1 \choose t}\\
&=[t=0]+\sum_v \sum_{y\in v} \left( {dis(v,y) \choose t} + {dis(v,y) \choose t-1} \right)\\
&=[t=0]+\sum_v (dp_{v,t} + dp_{v,t-1})
\end{align*}
\]

接下来是\(up\)。

\[\begin{align*}
up_{x,t}&=\sum_{y\notin x} {dis(x,y) \choose t}\\
&=\sum_{y\notin fa} {dis(fa,y)+1\choose t} +\sum_{y\in fa} {dis(fa,y)+1\choose t}-\sum_{y\in x} {dis(x,y)+2\choose t}\\
&=up_{fa,t}+up_{fa,t-1}+dn_{fa,t}+dn_{fa,t-1}-dn_{x,t}-2dn_{x,t-1}-dn_{x,t-2}
\end{align*}
\]

特判一下\(up_{1,t}=0\)即可。

至此,问题结束。

复杂度\(O(nk)\)。


代码

推了那么长的式子,代码其实超短。

#include<bits/stdc++.h>
namespace my_std{
using namespace std;
#define pii pair<int,int>
#define fir first
#define sec second
#define MP make_pair
#define rep(i,x,y) for (int i=(x);i<=(y);i++)
#define drep(i,x,y) for (int i=(x);i>=(y);i--)
#define go(x) for (int i=head[x];i;i=edge[i].nxt)
#define sz 50505
#define mod 10007
typedef long long ll;
typedef double db;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
template<typename T>inline T rnd(T l,T r) {return uniform_int_distribution<T>(l,r)(rng);}
template<typename T>inline void read(T& t)
{
t=0;char f=0,ch=getchar();double d=0.1;
while(ch>'9'||ch<'0') f|=(ch=='-'),ch=getchar();
while(ch<='9'&&ch>='0') t=t*10+ch-48,ch=getchar();
if(ch=='.'){ch=getchar();while(ch<='9'&&ch>='0') t+=d*(ch^48),d*=0.1,ch=getchar();}
t=(f?-t:t);
}
template<typename T,typename... Args>inline void read(T& t,Args&... args){read(t); read(args...);}
void file()
{
#ifndef ONLINE_JUDGE
freopen("a.txt","r",stdin);
#endif
}
#ifdef mod
ll ksm(ll x,int y){ll ret=1;for (;y;y>>=1,x=x*x%mod) if (y&1) ret=ret*x%mod;return ret;}
ll inv(ll x){return ksm(x,mod-2);}
#else
ll ksm(ll x,int y){ll ret=1;for (;y;y>>=1,x=x*x) if (y&1) ret=ret*x;return ret;}
#endif
// inline ll mul(ll a,ll b){ll d=(ll)(a*(double)b/mod+0.5);ll ret=a*b-d*mod;if (ret<0) ret+=mod;return ret;}
}
using namespace my_std; int n,K;
struct hh{int t,nxt;}edge[sz<<1];
int head[sz],ecnt;
void make_edge(int f,int t)
{
edge[++ecnt]=(hh){t,head[f]};
head[f]=ecnt;
edge[++ecnt]=(hh){f,head[t]};
head[t]=ecnt;
} ll up[sz][233],dn[sz][233];
#define v edge[i].t
void dfs1(int x,int fa)
{
dn[x][0]=1;
go(x) if (v!=fa)
{
dfs1(v,x);
(dn[x][0]+=dn[v][0])%=mod;
rep(j,1,K) (dn[x][j]+=dn[v][j]+dn[v][j-1])%=mod;
}
}
void dfs2(int x,int fa)
{
if (x!=1)
{
up[x][0]=(up[fa][0]+dn[fa][0]-dn[x][0]+mod)%mod;
up[x][1]=(up[fa][1]+up[fa][0]+dn[fa][1]+dn[fa][0]-dn[x][1]-2*dn[x][0]+mod*3)%mod;
rep(i,2,K) up[x][i]=(up[fa][i]+up[fa][i-1]+dn[fa][i]+dn[fa][i-1]-dn[x][i]-2*dn[x][i-1]-dn[x][i-2]+mod*4)%mod;
}
go(x) if (v!=fa) dfs2(v,x);
}
#undef v ll S[233][233];
ll fac[233]; int main()
{
file();
int x,y;
read(n,K);
rep(i,1,n-1) read(x,y),make_edge(x,y);
dfs1(1,0);dfs2(1,0);
fac[0]=1;rep(i,1,K) fac[i]=fac[i-1]*i%mod;
S[0][0]=1;
rep(i,1,K)
rep(j,1,K)
S[i][j]=(S[i-1][j-1]+1ll*j*S[i-1][j]%mod)%mod;
rep(i,1,n)
{
ll ans=0;
rep(j,0,K) ans=(ans+fac[j]*S[K][j]%mod*(up[i][j]+dn[i][j])%mod)%mod;
printf("%lld\n",ans);
}
return 0;
}

洛谷P4827 [国家集训队] Crash 的文明世界 [斯特林数,组合数,DP]的更多相关文章

  1. 洛谷 P4827 [国家集训队] Crash 的文明世界

    题目描述 ​ 给你一棵 n 个点的树,对于树上的每个节点 i,求 \(\sum_{j=1}^ndis(i,j)^k\).其中 \(dis(i,j)\) 为两点在树上的距离. 输入格式 ​ 第一行两个整 ...

  2. P4827 [国家集训队] Crash 的文明世界

    传送门:洛谷 题目大意:设$$S(i)=\sum_{j=1}^ndis(i,j)^k$$,求$S(1),S(2),\ldots,S(n)$. 数据范围:$n\leq 50000,k\leq 150$ ...

  3. 【BZOJ2159】Crash的文明世界 斯特林数+树形dp

    Description Crash 小朋友最近迷上了一款游戏--文明5(Civilization V).在这个游戏中,玩家可以建立和发展自己的国家,通过外交和别的国家交流,或是通过战争征服别的国家.现 ...

  4. BZOJ.2159.Crash的文明世界(斯特林数 树形DP)

    BZOJ 洛谷 挺套路但并不难的一道题 \(Description\) 给定一棵\(n\)个点的树和\(K\),边权为\(1\).对于每个点\(x\),求\(S(x)=\sum_{i=1}^ndis( ...

  5. P4827 [国家集训队] Crash 的文明世界(第二类斯特林数+树形dp)

    传送门 对于点\(u\),所求为\[\sum_{i=1}^ndis(i,u)^k\] 把后面那堆东西化成第二类斯特林数,有\[\sum_{i=1}^n\sum_{j=0}^kS(k,j)\times ...

  6. [BZOJ2159]Crash的文明世界(斯特林数+树形DP)

    题意:给定一棵树,求$S(i)=\sum_{j=1}^{n}dist(i,j)^k$.题解:根据斯特林数反演得到:$n^m=\sum_{i=0}^{n}C(n,i)\times i!\times S( ...

  7. [国家集训队] Crash 的文明世界(第二类斯特林数)

    题目 [国家集训队] Crash 的文明世界 前置 斯特林数\(\Longrightarrow\)斯特林数及反演总结 做法 \[\begin{aligned} ans_x&=\sum\limi ...

  8. 洛谷 P1829 [国家集训队]Crash的数字表格 / JZPTAB 解题报告

    [国家集训队]Crash的数字表格 / JZPTAB 题意 求\(\sum\limits_{i=1}^n\sum\limits_{j=1}^mlcm(i,j)\),\(n,m\le 10^7\) 鉴于 ...

  9. 国家集训队 Crash 的文明世界(第二类斯特林数+换根dp)

    题意 ​ 题目链接:https://www.luogu.org/problem/P4827 ​ 给定一棵 \(n\) 个节点的树和一个常数 \(k\) ,对于树上的每一个节点 \(i\) ,求出 \( ...

随机推荐

  1. Windows 查看某个端口号是否被占用

    Ø  前言 在 Windows 下很多系统或服务都需要使用独立的端口号,实现网络数据传输,如果需要知道某个端口号是否被占用,就可以使用下面步骤了. 1.   首先打开命令窗口,Windows + R ...

  2. 总结PHP如何获取当前主机、域名、网址、路径、端口和参数等

    //获取域名或主机地址 echo $_SERVER['HTTP_HOST']."<br />"; //获取网页地址 echo $_SERVER['PHP_SELF']. ...

  3. VS 中NuGet 尝试还原程序包时出错"*"已拥有为"**"定义的依赖项

    之前从Git检出项目以后,项目编译不能通过,发现是缺少依赖的外部插件,于是通过NuGet去获取项目依赖的插件,如何通过NuGet恢复使用的插件请使用NuGet还原项目插件. 但是就是在使用NuGet还 ...

  4. css哪些属性可以继承

    不可继承的:display.margin.border.padding.background.height.min-height.max- height.width.min-width.max-wid ...

  5. 委托(作用:解耦),lambda的演化

    1.了解委托 MyDelegate类代码如下: using System; using System.Collections.Generic; using System.Linq; using Sys ...

  6. JAVA配置文件/反射操作

    配置文件 1. 在src目录下新建一个file, 命名为XXX.properties 2.编写配置文件: 3. import java.util.ResourceBundle; 4. 使用如下代码读取 ...

  7. linux 文件搜索命令

  8. sonar排除实体类配置

    sonar覆盖率检查可以将一些实体类排除,maven项目可以在pom.xml文件中添加如下配置 <properties> <sonar.exclusions> src/main ...

  9. P1456 Monkey King

    题目地址:P1456 Monkey King 一道挺模板的左偏树题 不会左偏树?看论文打模板,完了之后再回来吧 然后你发现看完论文打完模板之后就可以A掉这道题不用回来了 细节见代码 #include ...

  10. C++ 11 snippets , 2

    <1>auto ,initializer_list<T>,auto指向函数指针的简易,和typdef 定义的类型执行函数指针有多复杂. #include <iostrea ...