考慮乙個特定形態的樹的貢獻,設點i的度數為d[i],那麼答案就是:
∑(∏wdii?di)
考慮prufer序,乙個度數為d[i]的點出現的次數是d[i]-1,那麼就可以得到乙個很顯然的dp,f[i][j]表示前i個點的度數為i+j:
fi,j=∑d=0jfi?1,j?d?(dn?2?(j?d))?wd+1i?(d+1)
這個dp是o(n3)的
即答案要求的是這樣乙個東西:
ans=∑d1+d2+?+dn=n?2(n?2)!∏di!?∏wdi+1i?(di+1)ans=∏wi?(n?2)!∑d1+d2+?+dn=n?21∏di!?∏wdii?(di+1)
然後考慮將(di+1)拆開,對於每個排列1≤p1考慮∏ki=1dpi的貢獻:
∑d1+d2+?+dn=n?21∏di!?∏wdii?∏dpi
將dpi與1dpi!中的1dpi消掉,得到:
∏wpi(∑d1+d2+?+dn=n?2?k∏wdiidi!)
這樣有什麼好處呢?可以看到後面的式子變成了這樣的形式:xii!
考慮生成函式:
fi(x)=ewi?x=∑i=0∞wiii!?xi
那麼前面的式子可以變成:
∏wpi([xn?2?k]∏fi(x))
有:∏wpi([xn?2?k]e(∑wi)?x)
∏wpi((∑wi)n?2?k(n?2?k)!)
綜上所述有:
ans=∏wi?(n?2)!?∑k=0n?2(∏1≤p1
中間那個可以直接o(n2)的dp處理(其實fft也是可以的)
所以總時間複雜度是o(n2)的
#include
#include
#include
#include
#include
#include
#include
#include
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
typedef long long ll;
typedef double db;
int get()
int s=ch-'0';
while(ch=getchar(),ch>='0'&&ch<='9')s=s*10+ch-'0';
return s;
}const int n = 2010;
const int mo = 1e+9+7;
int n;
ll a[n],js[n],ny[n],mi[n];
ll f[n];
ll quickmi(ll x,ll tim)
int main()
noi2017 整數 線段樹or模擬
orzyyb 題目大意 你需要維護乙個有 3 times 10 7 個二進位制位的數,有一種修改方式和一種詢問方式 對這個數加上 a times2 b 其中 a 10 9 b 3 times 10 7 保證需要維護的這個數始終非負 詢問這個數第k個二進位制位的值 總共有 10 6 次詢問 修改操作 ...
noi2017 整數 線段樹or模擬
orzyyb 題目大意 你需要維護乙個有 3 times 10 7 個二進位制位的數,有一種修改方式和一種詢問方式 對這個數加上 a times2 b 其中 a 10 9 b 3 times 10 7 保證需要維護的這個數始終非負 詢問這個數第k個二進位制位的值 總共有 10 6 次詢問 修改操作 ...
NOI2017模擬4 2 查詢 線段樹
給出若干條線段,用 x1,y1 x2,y2 表示其兩端點座標,現在要求支援兩種操作 0 x1 y1 x2 y2 表示加入一條新的線段,x1,y1 x2,y2 1 x0 詢問所有線段中,x座標在x0處的最高點的y座標是什麼,如果對應位置沒有線段,則輸出0。o nlog 2n 的 include inc...