題面:luogu
很久以前做的題了,今天重新推一遍。
\[s(i)=\sum_^ dist(i,j)^k
\]\[=\sum_^ \sum_^ s(k,t) \times t! \times
\]\[=\sum_^ s(k,t) \times t! \times \sum_^
\]設\(f(i,j)=\sum_^ \),那麼\(s(i)=\sum_^ s(k,t) \times t! \times f(i,t)\),現在考慮如何求\(f(i,j)\)。
觀察到有\(=+\),
這啟迪我們對於乙個點,可以先計算子樹內的貢獻。
不妨設\(g_1(i,j)\)表示子樹內的貢獻,\(g_2(i,j)\)表示子樹外的貢獻,
由上式知\(g_1(i,j)=\sum_ g_1(v,j-1)+g_1(v,j)(j\gt0)\),
這樣我們就計算了子樹內的貢獻。
那麼如何解決子樹外的貢獻呢?
仍然利用上面的思路,從上往下計算,
令\(tmp(v,j)=g_1(u,j)-g_1(v,j)-g_1(v,j-1)\),
那麼有\(g_2(v,j)=tmp(v,j)+tmp(v,j-1)+g_2(u,j-1)+g_2(u,j)\),
最後即可\(o(nk)\)得到\(f(i,j)\)。
// luogu-judger-enable-o2
#include#define n 50005
using namespace std;
const int p=1e4+7;
inline int in()
int n,k,h[n],e_tot=0,ans;
struct ee[n<<1];
inline void add(int u,int v); h[u]=e_tot;
}int s[155][155],fac[155];
inline void get_s_fac()
int g1[n][155],g2[n][155],tmp[155];
void dfs1(int u,int pre)
}void dfs2(int u,int pre)
}int main()
dfs1(1,-1); dfs2(1,-1);
for(int i=1;i<=n;++i)
return 0;
}
P4827 國家集訓隊 Crash 的文明世界
求出對於樹上每個點 x 的 sum ndis x,u k 所有邊長為 1。根據斯特林反演 m n sum n beginn j endc m jj 可以得到 sum n sum begink j endc jj sum begink j endj sum nc j sum begink j endj...
crash的實踐總結
大部分crash應該都是有空指標異常導致的 對於大部分的簡單的空指標異常,請相信編譯器。android studio中,對於大部分可能出現異常的情況,都會有相應的警告。請盡量處理編譯器的警告 大部分專案,應該eclipse中開發,可以轉換為android studio專案,或者將 複製到androi...
Crash 的文明世界
題目描述 給一棵樹,求以每個點為根時下列式子的值。題解 當k 1時這就是乙個經典的換根dp問題。所以這道題還是要用換根dp解決。部分分做法 考慮轉移時是這樣的乙個形式 圖是抄的 用二項式定理展開就可以nk2做了。觀察到結果是乙個xk的形式。然後這個可以用斯特林數代換。我們可以先求出每個點的後面的東西...