題解 Crash 的文明世界

2022-05-01 19:54:10 字數 1502 閱讀 2944

題目傳送門

給出乙個\(n\)個點的樹,和常數\(k\),對於\(\forall i\in[1,n]\),求出:

\[\sum_^ \text(i,j)^k

\]\(n\le 5\times 10^4,k\le 150\)

真的很妙,一開始完全沒有思路,看了\(\texttt\)的題解之後瞬間懂了。

我們考慮對於\(i\)如何計算答案,我們發現這個指數非常不好看,於是我們可以使用第二類斯特林數展開,就跟組合數問題差不多的,變為:

\[\sum_^\sum_^(i,j)}\binom(i,j)}\begink\\d\endd!

\]交換求和順序可以得到:

\[=\sum_^\begink\\d\endd!\sum_^\binom(i,j)}

\]於是,我們的問題就是如何快速求出後面那個\(\sum\)。我們想到這個東西可以拆成:

\[\binom(i,j)}=\binom(i,j)-1}+\binom(i,j)-1}

\]於是,我們用換根\(dp\)解決這個問題了。具體見**。

#include using namespace std;

#define int register int

#define maxn 50005

#define mod 10007

#define maxm 155

int qkpow (int a,int b)

int mul (int a,int b)

int dec (int a,int b)

int add (int a,int b)

struct edgee[maxn << 1];

int top = 1,head[maxn];

void add_edge (int u,int v),head[u] = top;

e[++ top] = edge ,head[v] = top;

} int n,k,s[maxm][maxm],fac[maxm],dp1[maxn][maxm],dp2[maxn][maxm],tmp[maxm];

//dp1[u][k]表示的是\sum_ \binom

//dp2[u][k]表示的是\sum_^ \binom

void dfs1 (int u,int fa)

}void dfs2 (int u,int fa)

for (int i = head[u];i;i = e[i].nxt)

}template inline void read (t &t)while (c >= '0' && c <= '9') t *= f;}

template inline void read (t &t,args&... args)

template inline void write (t x)if (x > 9) write (x / 10);putchar (x % 10 + '0');}

signed main()

return 0;

}

Crash 的文明世界

題目描述 給一棵樹,求以每個點為根時下列式子的值。題解 當k 1時這就是乙個經典的換根dp問題。所以這道題還是要用換根dp解決。部分分做法 考慮轉移時是這樣的乙個形式 圖是抄的 用二項式定理展開就可以nk2做了。觀察到結果是乙個xk的形式。然後這個可以用斯特林數代換。我們可以先求出每個點的後面的東西...

BZOJ2159 Crash 的文明世界

這篇寫差分表和斯特林數介紹的不錯 這題就是要計算這個東西 s i j 1n dist i,j ks i j 1nd ist i,j k這個東西很難維護,我們把di st i j k d is t i,j k拆一下s u v kj 0d u,v d u,v j s u v j 0 kd u v d u...

bzoj 2159 Crash 的文明世界

又來做了一次。之前寫得實在是太差了,這次寫好點吧。這裡介紹用斯特林數展開的方法 如果不會的可以先看看這裡 我們知道xn k 0 ns n k k c x,k x n sum ns n,k k c x,k xn k 0n s n,k k c x k 因此,如果想知道答案,其實就是要知道對於每乙個k k...