日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

YbtOJ-森林之和【dp】

發布時間:2023/12/3 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 YbtOJ-森林之和【dp】 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

正題


題目大意

一個節點的權值定義為它度數的平方,求所有nnn個點的有標號森林的所有節點權值和。

1≤n,T≤5×1031\leq n,T\leq 5\times 10^31n,T5×103


解題思路

首先因為所有節點本質相同,所以我們可以只考慮一個節點所有情況下的權值和。

然后考慮這個平方和怎么做,我們可以視為指定一個節點連出兩顆子樹的方案(可以相同)。

那么考慮這個怎么做,首先我們需要處理出nnn個節點有根樹和無根樹的數組r,fr,fr,f

然后我們要考慮怎么統計除了指定子樹以外的方案,首先我們需要處理出nnn個點的森林個數sns_nsn?。

我們可以考慮每次枚舉新加入的樹的大小,但是要指定這個節點編號最小的節點編號必須是111(以防相同的子樹算重),那么有
sn=∑i=1nsn?ifi(n?1i?1)s_n=\sum_{i=1}^ns_{n-i}f_{i}\binom{n-1}{i-1}sn?=i=1n?sn?i?fi?(i?1n?1?)
然后還要算上非指定的子樹中和111號點聯通的其他節點的方案,那么有
gn=∑i=0nsiri+1(ni)g_n=\sum_{i=0}^ns_ir_{i+1}\binom{n}{i}gn?=i=0n?si?ri+1?(in?)
至于指定子樹的話,我們枚舉指定子樹的大小轉移就好了。

時間復雜度:O(n2+T)O(n^2+T)O(n2+T)


code

#include<cstdio> #include<cstring> #include<algorithm> #define ll long long using namespace std; const ll N=5100; ll T,P,C[N][N],f[N],r[N],g[N],s[N],d[N],ans[N]; ll power(ll x,ll b){ll ans=1;while(b){if(b&1)ans=ans*x%P;x=x*x%P;b>>=1;}return ans; } signed main() {freopen("forest.in","r",stdin);freopen("forest.out","w",stdout);scanf("%lld%lld",&T,&P);C[0][0]=1;for(ll i=1;i<N;i++)for(ll j=0;j<=i;j++)C[i][j]=(C[i-1][j]+(j?C[i-1][j-1]:0))%P;f[0]=f[1]=r[0]=r[1]=g[0]=s[0]=1;for(ll i=2;i<N;i++) f[i]=power(i,i-2),r[i]=f[i]*i%P;for(ll i=1;i<N;i++)for(ll j=0;j<i;j++)(s[i]+=s[j]*f[i-j]%P*C[i-1][j]%P)%=P;for(ll i=1;i<N;i++){for(ll j=0;j<=i;j++)(g[i]+=s[j]*f[i-j+1]%P*C[i][j]%P)%=P;for(ll j=1;j<i;j++)(ans[i]+=r[j]*g[i-j-1]%P*C[i-1][j]%P)%=P;}for(ll i=1;i<N;i++){d[i]=ans[i+1]; // for(ll j=1;j<=i;j++) // (d[i]+=r[j]*g[i-j]%P*C[i][j]%P)%=P;for(ll j=1;j<i-1;j++)(ans[i]+=d[j]*r[i-j-1]%P*C[i-1][j]%P)%=P;}while(T--){ll n;scanf("%lld",&n);printf("%lld\n",ans[n]*n%P);}return 0; } 創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的YbtOJ-森林之和【dp】的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。