集訓隊互測2013 城市規劃

2021-08-09 01:43:58 字數 1901 閱讀 6768

求n個點的帶標號連通簡單圖的個數。答案對1004535809取模。

n<=130000

根據套路,首先我們需要求出n個點的帶標號簡單圖的個數,設為g[n]

顯然我們有g[n]=2^(n*(n-1)/2)

考慮設答案為f[n],要怎麼求出?

列舉1號點所在的聯通塊的大小,我們可以知道 g[

n]=∑

i=1n

f[i]

ci−1

n−1g

[n−i

] 因為f是保證聯通的所以不會算重

把g帶入,c拆開 2n

∗(n+

1)/2

=∑i=

1nf[

i](n

−1)!

(i−1

)!(n

−i)!

2(n−

i)∗(

n−i−

1)/2

兩邊同除(n-1)! 2n

∗(n+

1)/2

(n−1

)!=∑

i=1n

f[i]

(i−1

)!2(

n−i)

∗(n−

i−1)

/2(n

−i)!

可以發現這是乙個卷積的形式

那麼我們就直接上fft就好了

需要多項式求逆

第一次寫寫的很醜qwq

#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;

ll read()

void write(int

x) char ch[20];int tot=0;

for(;x;x/=10) ch[++tot]=x

%10+'0';

fd(i,tot,1) putchar(ch[i]);

puts("");

}const int mo=1004535809,d=3,n=5

*1e5+5;

int pwr(int

x,ll y)

int n,len,lg,inv,t[n],a[n],b[n],c[n],w[n];

int p[n],h[n],g[n],f[n];

void pre(int len)

void dft(int *a,int len,int lg,int flag)

for(int

m=2;m

<=len;m

<<=1) }}

for(int i=0;iif (flag==-1) for(int i=0;i*inv

%mo;

}void ntt(int

*a,int

*b,int

*c,int len,int lg)

for(int i=0;i*2);

ntt(p,b,h,len*2,lg+1);

for(int i=0;i*2;i++) h[i]=mo-h[i];

(h[0]+=2)%=mo;

ntt(h,b,b,len*2,lg+1);

for(int i=len;i*2;i++) b[i]=0;

} }int fact[n],inv[n],f[n],g[n],inv_g[n],h[n];

int main()

upd:聽說一次倍增只需要3次dft qwq

結果我常數直接*2壓倒性劣勢

集訓隊作業 城市規劃

點這裡看題目。考慮如下遞推 f i i 個點的無向有標號連通圖的個數。g i i 個點的無向有標號圖的個數。以下給出兩種計算方式。不難看出乙個式子 g n sum n binomf ig 這相當於列舉 1 所在的連通塊大小,然後構造出這個連通塊,剩下的點任意連。然後感覺這個東西非常的 egf 就嘗試...

P4841 集訓隊作業2013 城市規劃

設 f i 表示 i 個點的無向連通圖個數,g i 表示 i 個點的無向圖個數。列舉 1 所在連通塊的大小,有 g i sum limits ic f jg 化簡得 g i sum limits i fracf jg frac sum limits i frac frac 設 f i frac,g ...

P4841 集訓隊作業2013 城市規劃 題解

求 n 個點的有標號的無向連通圖數目。text 1 le n le1.3 times10 5 我們設 g i 表示有 i 個點的有標號無向圖數目,易得 g i 2 考慮列舉每兩個點之間是否連通。設 f i 表示有 i 個點的連通圖數目 即答案所求 則可得 g n sum n c f i g 考慮 1...