Time Limit 3s
Memory Limit 512M
Description
认定两个黑白二分图不同当且仅当某两个点在一个二分图中有边在另一个中没边,或者在两个图中边颜色不同,求n个点的不同的黑白二分图的个数
Input
第一行T数据组数,然后T行每行n
Output
每行一个答案对998244353取模
Sample
Input
3
2
3
10
Output
3
19
435363530
Data Constraint
n
≤
1
0
5
n\leq 10^5
n≤105
考虑将n分为多个联通块,设一个大小为n的联通快的方案数的生成函数为
f
(
x
)
f(x)
f(x),
E
G
F
(
f
)
=
F
(
x
)
EGF(f)=F(x)
EGF(f)=F(x)
答案就是
n
!
∗
[
x
n
]
e
F
(
x
)
n!*[x^n]e^{F(x)}
n!∗[xn]eF(x)
这里
n
!
n!
n!乘的是里面的
E
G
F
EGF
EGF,而外面
e
F
(
x
)
=
∑
F
(
x
)
i
i
!
e^{F(x)}=\sum \frac{F(x)^i}{i!}
eF(x)=∑i!F(x)i,除
i
!
i!
i!是为了避免选取的
i
i
i个被重复计算
i
!
i!
i!次
显然,不好推
考虑
g
(
x
)
g(x)
g(x)为
∑
x
+
y
=
n
(
n
x
)
3
x
y
\sum_{x+y=n}{n\choose x}3^{xy}
∑x+y=n(xn)3xy的生成函数,其EGF为
G
(
x
)
G(x)
G(x),这样是不考虑这一块是否联通的,那么如果这里有k个联通快,由于左右两部可以互换,重复算了
2
k
2^k
2k次,有关系式
G
(
x
)
=
∑
F
(
x
)
i
2
i
i
!
=
e
2
F
(
x
)
G(x)=\sum \frac{F(x)^i2^i}{i!}=e^{2F(x)}
G(x)=∑i!F(x)i2i=e2F(x),那么
e
F
(
x
)
=
G
(
x
)
e^{F(x)}=\sqrt{G(x)}
eF(x)=G(x)
Part 1
如何求G(x)呢
二次剩余??很遗憾3在摸998244353下无二次剩余。。。
[
x
n
]
G
(
x
)
=
∑
i
+
j
=
n
(
n
i
)
3
i
j
n
!
=
3
n
2
2
∗
∑
i
+
j
=
n
3
−
i
2
2
i
!
×
3
−
j
2
2
j
!
\begin{aligned} [x^n]G(x) & = \frac{\sum_{i+j=n} {n\choose i}3^{ij}}{n!} \\ & =3^\frac{n^2}2*\sum_{i+j=n} \frac{3^\frac{-i^2}2}{i!}\times\frac{3^\frac{-j^2}2}{j!} \\ \end{aligned}
[xn]G(x)=n!∑i+j=n(in)3ij=32n2∗i+j=n∑i!32−i2×j!32−j2这个分奇偶数讨论一下就好了
Part 2
多项式开根
假设原式为A(x)
假设
G
(
x
)
2
≡
A
(
x
)
(
m
o
d
  
x
n
2
)
G(x)^2\equiv A(x)(\mod x^\frac n2)
G(x)2≡A(x)(modx2n)
B
(
x
)
2
≡
A
(
x
)
(
m
o
d
  
x
n
)
B(x)^2\equiv A(x)(\mod x^n)
B(x)2≡A(x)(modxn)
这时
B
(
x
)
−
G
(
x
)
≡
0
(
m
o
d
  
x
n
2
)
(
B
(
x
)
−
G
(
x
)
)
2
≡
0
(
m
o
d
  
x
n
)
B
2
(
x
)
−
2
B
(
x
)
G
(
x
)
+
G
2
(
x
)
≡
0
(
m
o
d
  
x
n
)
A
(
x
)
−
2
B
(
x
)
G
(
x
)
+
G
2
(
x
)
≡
0
(
m
o
d
  
x
n
)
B
(
x
)
≡
G
(
x
)
2
+
A
(
x
)
2
G
(
x
)
(
m
o
d
  
x
n
)
\begin{aligned} B(x)-G(x) & \equiv 0(\mod x^\frac n2)\\ (B(x)-G(x))^2 & \equiv 0 (\mod x^n)\\ B^2(x) -2B(x)G(x) + G^2(x) & \equiv 0(\mod x^n)\\ A(x)-2B(x)G(x)+G^2(x) & \equiv 0(\mod x^n)\\ B(x) & \equiv \frac {G(x)}2+\frac{A(x)}{2G(x)}(\mod x^n)\\ \end{aligned}
B(x)−G(x)(B(x)−G(x))2B2(x)−2B(x)G(x)+G2(x)A(x)−2B(x)G(x)+G2(x)B(x)≡0(modx2n)≡0(modxn)≡0(modxn)≡0(modxn)≡2G(x)+2G(x)A(x)(modxn)
这时就只需要知道答案的常数项就好了
这题A的常数项为1,比较特殊
不然用二次剩余具体是这样:
勒让德符号
(
n
p
)
(\frac np)
(pn)
(
n
p
)
=
n
p
−
1
2
=
{
1
,
存
在
二
次
剩
余
0
,
n
=
0
−
1
,
不
存
在
二
次
剩
余
(
m
o
d
  
p
)
(\frac np)=n^\frac {p-1}2= \begin{cases} 1 &, 存在二次剩余\\ 0 &, n=0\\ -1 &, 不存在二次剩余\\ \end{cases} (\mod p)
(pn)=n2p−1=⎩⎪⎨⎪⎧10−1,存在二次剩余,n=0,不存在二次剩余(modp)
加入n有实根
要找
a
2
=
n
(
m
o
d
  
p
)
a^2=n(\mod p)
a2=n(modp),先随机一个
(
t
2
−
n
p
)
=
−
1
(\frac{t^2-n}p)=-1
(pt2−n)=−1,令
w
=
t
2
−
n
(
可
以
看
作
是
复
数
根
)
w=\sqrt{t^2-n}(可以看作是复数根)
w=t2−n(可以看作是复数根),那么
a
=
(
1
−
w
)
p
+
1
2
(
显
然
这
个
只
有
实
部
)
a=(1-w)^\frac{p+1}2(显然这个只有实部)
a=(1−w)2p+1(显然这个只有实部)
Part 3
如何去求
A
(
x
)
2
G
(
x
)
\frac{A(x)}{2G(x)}
2G(x)A(x)?考虑求
1
G
(
x
)
\frac 1{G(x)}
G(x)1
多项式求逆!
同开根的思路
设
B
(
x
)
A
(
x
)
≡
1
(
m
o
d
  
x
n
)
B(x)A(x)\equiv 1(\mod x^n)
B(x)A(x)≡1(modxn)
G
(
x
)
A
(
x
)
≡
1
(
m
o
d
  
x
n
2
)
G(x)A(x)\equiv 1(\mod x^\frac n2)
G(x)A(x)≡1(modx2n)
同理
B
(
x
)
−
G
(
x
)
≡
0
(
m
o
d
  
x
n
2
)
(
B
(
x
)
−
G
(
x
)
)
2
≡
0
(
m
o
d
  
x
n
)
B
2
(
x
)
−
2
B
(
x
)
G
(
x
)
+
G
2
(
x
)
≡
0
(
m
o
d
  
x
n
)
B
(
x
)
−
2
G
(
x
)
+
G
2
(
x
)
A
(
x
)
≡
0
(
m
o
d
  
x
n
)
B
(
x
)
≡
2
G
(
x
)
−
A
(
x
)
G
2
(
x
)
(
m
o
d
  
x
n
)
\begin{aligned} B(x)-G(x) & \equiv 0(\mod x^\frac n2)\\ (B(x)-G(x))^2 & \equiv 0 (\mod x^n)\\ B^2(x) -2B(x)G(x) + G^2(x) & \equiv 0(\mod x^n)\\ B(x)-2G(x)+G^2(x)A(x) & \equiv 0(\mod x^n)\\ B(x) & \equiv 2G(x)-A(x)G^2(x)(\mod x^n)\\ \end{aligned}
B(x)−G(x)(B(x)−G(x))2B2(x)−2B(x)G(x)+G2(x)B(x)−2G(x)+G2(x)A(x)B(x)≡0(modx2n)≡0(modxn)≡0(modxn)≡0(modxn)≡2G(x)−A(x)G2(x)(modxn)
答案的常数项就是A的常数项的逆元
Details
求你开根的次数界要开两倍,每次做完要将
n
−
2
n
n-2n
n−2n的删掉
#include<cstring>
#include<cstdio>
#include<algorithm>
#define mo 998244353
#define REP(i,a,b) for(int i=a,___=b;i<___;++i)
#define fo(i,a,b) for(int i=a,___=b;i<=___;++i)
#define fd(i,a,b) for(int i=a,___=b;i>=___;--i)
#define M 600100
#define n2 499122177
#define ny 332748118
#define L 131071
#define P 524288
#define ll long long
using namespace std;
int G[M],n,N,a[M],b[M],t[M],T[M],w[M],rev[M],fr[M],ifr[M],tri[M],itri[M];
ll sqr(ll a){return a*a%mo;}
ll qpow(ll a,ll i){
ll r=1;for(;i;i>>=1,a=a*a%mo)if(i&1)r=r*a%mo;return r;
}
void ntt(int *a){
REP(i,1,N)rev[i]=(rev[i>>1]>>1)+(i&1)*(N>>1),swap(a[i],a[max(rev[i],i)]);
for(int h=1,m=2;h<N;h=m,m<<=1)REP(i,0,h)for(int j=i,k,T;j<N;j+=m)
k=j+h,T=1ll*w[P/m*i]*a[k]%mo,a[k]=(a[j]+mo-T)%mo,a[j]=(a[j]+T)%mo;
}
void intt(int *a){
REP(i,1,N>>1)swap(a[i],a[N-i]);ntt(a);
ll n=qpow(N,mo-2);REP(i,0,N)a[i]=n*a[i]%mo;
}
void inv(int *A){
REP(i,0,N<<1)a[i]=T[i]=0;
a[0]=qpow(A[0],mo-2);int n=N;
for(N=2;N<=n;){
REP(i,0,N)T[i]=A[i];
N<<=1;ntt(T);ntt(a);
REP(i,0,N)a[i]=(2ll*a[i]+mo-1ll*a[i]*a[i]%mo*T[i]%mo)%mo;
intt(a);REP(i,N>>1,N)a[i]=0;
}N>>=1;REP(i,0,N)A[i]=a[i];
}
void sqroot(int *A){
REP(i,0,N<<1)b[i]=t[i]=0;
b[0]=1;int n=N;
for(N=2;N<=n;){
REP(i,0,N)t[i]=b[i];inv(t);
REP(i,0,N)T[i]=A[i];REP(i,N,N<<1)T[i]=0;
N<<=1;ntt(t);ntt(T);ntt(b);
REP(i,0,N)b[i]=(1ll*T[i]*n2%mo*t[i]+1ll*b[i]*n2)%mo;
intt(b);REP(i,N>>1,N)b[i]=0;
}N>>=1;REP(i,0,N)A[i]=b[i];
}
int main(){
ll W=qpow(3,(mo-1)/P);w[0]=1;REP(i,1,P)w[i]=W*w[i-1]%mo;
fr[0]=ifr[0]=tri[0]=itri[0]=1;fo(i,1,L)fr[i]=1ll*fr[i-1]*i%mo;
ifr[L]=qpow(fr[L],mo-2);fd(i,L-1,1)ifr[i]=1ll*ifr[i+1]*(i+1)%mo;
fo(i,1,L)tri[i]=3ll*tri[i-1]%mo,itri[i]=1ll*ny*itri[i-1]%mo;
fo(i,0,L)if(i&1)a[i]=sqr(qpow(itri[i>>1],i+1>>1))*ifr[i]%mo;
else b[i]=sqr(qpow(itri[i>>1],i>>1))*ifr[i]%mo;
N=262144;ntt(a);ntt(b);
REP(i,0,N)G[i]=(1ll*a[i]*a[i]%mo*ny+1ll*b[i]*b[i]+2ll*a[i]*b[i])%mo;
intt(G);
REP(i,0,N)if(i&1)G[i]=sqr(qpow(tri[i>>1],i+1>>1))*G[i]%mo;
else G[i]=sqr(qpow(tri[i>>1],i>>1))*G[i]%mo;
sqroot(G);
scanf("%d",&n);fo(i,1,n)scanf("%d",&n),printf("%d\n",1ll*G[n]*fr[n]%mo);
}