剛剛解決完電力網路的問題, 阿狸又被領導的任務給難住了.
剛才說過, 阿狸的國家有n個城市, 現在國家需要在某些城市對之間建立一些**路線, 使得整個國家的任意兩個城市都直接或間接的連通. 為了省錢, 每兩個城市之間最多只能有一條直接的**路徑. 對於兩個建立路線的方案, 如果存在乙個城市對, 在兩個方案中是否建立路線不一樣, 那麼這兩個方案就是不同的, 否則就是相同的. 現在你需要求出一共有多少不同的方案.
好了, 這就是困擾阿狸的問題. 換句話說, 你需要求出n個點的簡單(無重邊無自環)無向連通圖數目.
由於這個數字可能非常大, 你只需要輸出方案數mod 1004535809(479 * 2 ^ 21 + 1)即可.
僅一行乙個整數n(<=130000)
僅一行乙個整數, 為方案數 mod 1004535809.
3 4
對於 100%的資料, n <= 130000 令
f(i)
表示有i個點的無向連通圖的個數,g(
i)表示有
i 個點的無向圖的個數。 顯然g
(i)=
2(i2
)我們通過列舉一號節點所在連通塊的大小來轉移。 g(
i)=∑
j=1i
(i−1
j−1)
f(j)
g(i−
j)=∑
j=1i
(i−1
)!(j
−1)!
(n−j
)!f(
j)g(
i−j)
g(i)
(i−1
)!=f
(j)(
j−1)
!g(i
−j)(
i−j)
! 令a
i=g(
i)(i
−1)!
bi=f
(j)(
j−1)
!ci=
g(i−
j)(i
−j)!
特別地,根據式子可以看出,a0
=0 a
(x)=
b(x)
c(x)
b(x)
=a(x
)÷c(
x)將其放在
modxn+
1 意義下 b(
x)=a
(x)c
(x)−
1 然後就可以求出bn
,然後算出f(
n)
#include
#include
#define mod 1004535809
#define g 3
#define maxn 130000
using namespace std;
int n,f[maxn*2+10000],g[maxn*2+10000],c[maxn*2+10000],n,fac[maxn+10],inv[maxn+10],gr[maxn*2+10000],tmp[maxn*2+10000];
void read(int &x)
}int quick_pow(int a,int b)
return ret;
}void ntt(int
*a,int n,int f)}}
if(f==-1)
}void divide_conqure(int n,int
*a,int
*b) int mid((n+1)>>1),i,n;
divide_conqure(mid,a,b);
for(n=1;n<(n<<1)-1;n<<=1);
for(i=0;ifor(i=n;i0;
ntt(tmp,n,1);
ntt(b,n,1);
for(i=0;i*2-1ll*tmp[i]*b[i]%mod
*b[i]%mod)+mod)%mod;
ntt(b,n,-1);
for(i=n;i0;
}void prepare()
}void solve()
for(n=1;n*2+1;n<<=1);
g[0]=1;
ntt(c,n,1);
divide_conqure(n+1,g,gr);
ntt(gr,n,1);
for(i=0;i1ll*gr[i]*c[i]%mod;
ntt(f,n,-1);
}int main()
BZOJ3456 城市規劃 多項式求逆
剛剛解決完電力網路的問題,阿狸又被領導的任務給難住了.剛才說過,阿狸的國家有n個城市,現在國家需要在某些城市對之間建立一些 路線,使得整個國家的任意兩個城市都直接或間接的連通.為了省錢,每兩個城市之間最多只能有一條直接的 路徑.對於兩個建立路線的方案,如果存在乙個城市對,在兩個方案中是否建立路線不一...
BZOJ 3456 城市規劃 dp 多項式求逆
傳送門 這道題就是求帶標號的無向連通圖個數,首先考慮 o n 2 的做法,設 f i 表示有 i 個節點的無向連通圖個數,那麼考慮容斥,先把所有的無向圖求出,即為 2 再減去不聯通的情況,而計算不聯通情況時可以列舉 1 號點這個聯通塊的大小,就有方程 f i 2 sum limits c 2 f j...
BZOJ3456 城市規劃(多項式求逆 NTT)
點此看題面 大致題意 求出 n 個點的簡單 無重邊無自環 有標號無向連通圖數目。在我的想象裡,這道題應該是無比冗長 十分複雜 令人懵逼的題面 極其恐怖 難以理解 又臭又長的式子 分治 ntt 多項式求逆 多項式對數 指數型生成函式 一堆五花八門 亂七八糟的東西。然而真正點開這道題,題面簡潔明瞭 就一...