不错的树形$ 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. MVC过滤器处理Session过期

    一.自定义一个Action过滤器 public class CheckSession: ActionFilterAttribute { public override void OnActionExe ...

  2. (转)source insight的使用方法逆天整理

    转载自:https://www.cnblogs.com/xunbu7/p/7067427.html A. why SI: 为什么要用Source Insight呢?因为她比完整的IDE要更快啊,比一般 ...

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

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

  4. java的线程

    public class Test1 extends Thread{ public void run(){ // } } public class Test2 immplement Runnable{ ...

  5. appium 切换native/ webview,findby,还有页面元素定位一直小于0的问题的解决

    之前一直有个bug没有解决. 今天,终于解决了. 疑问过程: app是混合应用,项目做了H5优化之后,以前的用例执行总会失败,体现在原来的一个元素点击无反馈 排查原因:1.项目做了H5优化,2.测试的 ...

  6. Unity 着色器基础知识

    一.着色器基础知识 着色器通过代码模拟物体表面发生的事情,其实就是GPU中运行的一段代码. 着色器的类型: 顶点着色器.片元着色器.无光照着色器.表面着色器.图像特效着色器.计算着色器. 坐标空间: ...

  7. Linux之LVS 20180708

    LVS负载均衡项目,是Linux开源项目中专门用于负载均衡的,主要应用在client访问server时,通过LVS来分配对应的server来响应client的请求.client访问时,都是访问的LVS ...

  8. Luogu P2292 [HNOI2004]L语言

    题目链接 \(Click\) \(Here\) 好久没写\(DP\)了真是水平下降不少,一眼把这个题搞成贪心了,然后一发交上只有\(37\)分\(QwQ\) 这个题好像还可以\(AC\)自动机胡搞?不 ...

  9. bzoj2243 树链剖分

    https://www.lydsy.com/JudgeOnline/problem.php?id=2243 新学的树剖,在维护的时候线段树维护区间内颜色数量以及左右两端的颜色.统计的时候区间合并时判断 ...

  10. 怎么正确的回滚git的代码?

    1. git reflog或者git log查看到节点的hash值 2. git reset滚回某个节点 1)如果想保留当前的代码用 git reset --mixed ${Hash} 2)如果想联通 ...