題目傳送門
給出乙個\(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...