不错的树形$ DP$的题

可为什么我自带大常数啊$ cry$

链接:here


题意:给定一棵$ n$个节点的树,边权为$ 1$,对于每个点$ x$求$ \sum\limits_{i=1}^n dist(x,i)^k$

数据范围:$ n<=50000,k<=150$


$ Solution$

直接推式子

上下$ DP$先考虑子树内的贡献

有$ in(x)^k=\sum\limits (in(son[x])+1)^k$

这是因为自己子树内的每个点到自己的距离都$ ++$

再考虑子树外的贡献

有$ out(x)^k=(out(fa[x])+1)^k+(in(fa[x])+1)^k-(in(x)+2)^k$

这是因为父亲节点子树外的节点和父亲子树中除自己外其他子树内的节点到自己的距离相比原先都$ ++$

而自己这棵子树内不增反减所以再$ -=2$

直接二项式展开是$ nk^2$的

不过这类式子可以转化成斯特林数

我们只要从求$ in(x)^k/out(x)^k$转化成求$ C_{in(x)/out(x)}^k$即可

这样$ C_{in(x)}^k=\sum\limits C_{in(son[x])+1}^k=\sum\limits C_{in(son[x])}^k+C_{in(son[x])}^{k-1}$

求$ out$的时候同理,唯一的区别是$ C_{in(x)+2}^k$需要展开两层

代码还是比较清真的

$ my \ code$

#include<ctime>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#define p 10007
#define M 100010
#define rt register int
#define ll long long
using namespace std;
inline ll read(){
ll x = ; char zf = ; char ch = getchar();
while (ch != '-' && !isdigit(ch)) ch = getchar();
if (ch == '-') zf = -, ch = getchar();
while (isdigit(ch)) x = x * + ch - '', ch = getchar(); return x * zf;
}
void write(ll y){if(y<)putchar('-'),y=-y;if(y>)write(y/);putchar(y%+);}
void writeln(const ll y){write(y);putchar('\n');}
int i,j,k,m,n,x,y,z,cnt;
int val[][],out[][],fa[];
int F[M],L[M],N[M],a[M];
void add(int x,int y){
a[++k]=y;
if(!F[x])F[x]=k;
else N[L[x]]=k;
L[x]=k;
}
void dfs(int x,int pre){
fa[x]=pre;val[x][]=;
for(rt i=F[x];i;i=N[i])if(a[i]!=pre){
dfs(a[i],x);
(val[x][]+=val[a[i]][])%=p;
}
out[x][]=n-val[x][];
}
void get(int x){
for(rt i=F[x];i;i=N[i])if(a[i]!=fa[x]){
get(a[i]);
for(rt j=;j<=m;j++)
(val[x][j]+=val[a[i]][j]+val[a[i]][j-])%=p;
}
}
int S[][],inv[];
void up(int x){
for(rt j=;j<=m;j++)
if(x==)out[x][j]=;
else out[x][j]=(out[fa[x]][j]+out[fa[x]][j-]+val[fa[x]][j]+val[fa[x]][j-]-(val[x][j-]*+val[x][j]+val[x][j-]))%p;
for(rt i=F[x];i;i=N[i])if(a[i]!=fa[x])up(a[i]);
}
int main(){
n=read();m=read();
for(rt i=;i<n;i++){
x=read();y=read();
add(x,y);
add(y,x);
}
dfs(,);get();up();
for(rt i=;i<=n;i++)
for(rt j=;j<=m;j++)val[i][j]+=out[i][j];
S[][]=;
for(rt i=;i<=m;i++)
for(rt j=;j<=i;j++)
S[i][j]=(S[i-][j-]+j*S[i-][j])%p;
inv[]=inv[]=;
for(rt i=;i<=m+;i++)inv[i]=inv[p%i]*(p-p/i)%p;
for(rt i=;i<=n;i++){
ll ans=,C=,jc=;
for(rt j=;j<=m;j++){
(ans+=val[i][j]*S[m][j]*jc)%=p;
jc=jc*(j+)%p;
}
writeln((ans+p)%p);
}
return ;
}

[国家集训队] Crash 的文明世界的更多相关文章

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

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

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

    Description 给定一棵 \(n\) 个点的树,对于每个点 \(i\) 求 \(S(i)=\sum\limits_{j=1}^n \operatorname{dist(i,j)}^k\) .\ ...

  3. 洛谷P4827 [国家集训队] Crash 的文明世界 [斯特林数,组合数,DP]

    传送门 思路 又见到这个\(k\)次方啦!按照套路,我们将它搞成斯特林数: \[ ans_x=\sum_{i=0}^k i!S(k,i)\sum_y {dis(x,y) \choose i} \] 前 ...

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

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

  5. 解题:国家集训队 Crash 的文明世界

    题面 这种套着高次幂的统计问题一般都要用到第二类斯特林数和自然数幂的关系:$a^k=\sum\limits_{i=0}^{k}S_k^iC_a^i*i!$ 那么对于每个点$x$有: $ans_x=\s ...

  6. 【[国家集训队] Crash 的文明世界】

    先写一个五十分的思路吧 首先这道题有一个弱化版 [POI2008]STA-Station 相当于\(k=1\),于是就是一个非常简单的树形\(dp\)的\(up\ \ and\ \ down\)思想 ...

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

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

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

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

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

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

随机推荐

  1. [luogu3391][文艺平衡树]

    题目链接 思路 splay区间操作的裸题. 假如要对l-r这段区间操作,那么就先把l-1伸展到根节点,然后把r +1伸展为根的儿子.这样r + 1的左儿子就是要操作的区间了.只要在上面打上标记,以后每 ...

  2. 使用webdriver+urllib爬取网页数据(模拟登陆,过验证码)

    urilib是python的标准库,当我们使用Python爬取网页数据时,往往用的是urllib模块,通过调用urllib模块的urlopen(url)方法返回网页对象,并使用read()方法获得ur ...

  3. 函数:PHP将字符串从GBK转换为UTF8字符集iconv

    1. iconv()介绍 iconv函数可以将一种已知的字符集文件转换成另一种已知的字符集文件.例如:从GB2312转换为UTF-8. iconv函数在php5中内置,GB字符集默认打开. 2. ic ...

  4. Luogu P2617 Dynamic Rankings

    带修主席树的模板,因为状态不好所以敲了很长时间,不过写完感觉能更好地理解主席树了. 核心其实就是树状数组套主席树,维护方法不再是以前的那种一步一修改,而是对于树状数组上的每一个点建立一棵权值线段树,然 ...

  5. Nginx 性能优化有这篇就够了!

    目录: 1.Nginx运行工作进程数量 Nginx运行工作进程个数一般设置CPU的核心或者核心数x2.如果不了解cpu的核数,可以top命令之后按1看出来,也可以查看/proc/cpuinfo文件 g ...

  6. Go-day07

    今日内容概要: 1.json解析 2.文件操作 3.命令行参数 4.错误处理 一.Golang里的类型断言 1 em必须为initerface类型才可以进行类型断言 比如如下代码会报错 s := &q ...

  7. maven编译或者打包web项目显示“软件包 javax.servlet.http 不存在"

    2.解决办法: 这是由于缺少servlet-api.jar包,其实tomcat下有,但是在java build path把他加载过来,还是报这个错误,所以我们直接在pom.xml里面加入这个jar包即 ...

  8. percona-5.7二进制多实例安装

    percona-mysql-5.7二进制多实例安装 规划:端口号     配置文件     备注3306 /data/mysql/mysql_3306/my_3306.cnf 3307 /data/m ...

  9. 如何修改Tomcat的默认项目发布路径

    tomcat默认的项目发布目录是/webapp/ROOT,如果想自定义发布目录,应该怎么办呢? 修改配置文件 首先,修改$tomcat/conf/server.xml文件. 在server.xml文件 ...

  10. 剑指Offer_编程题_8

    题目描述 一只青蛙一次可以跳上1级台阶,也可以跳上2级.求该青蛙跳上一个n级的台阶总共有多少种跳法. class Solution { public: int jumpFloor(int number ...