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≤105n\leq 10^5n≤105
考虑将n分为多个联通块,设一个大小为n的联通快的方案数的生成函数为f(x)f(x)f(x),EGF(f)=F(x)EGF(f)=F(x)EGF(f)=F(x)
答案就是n!∗[xn]eF(x)n!*[x^n]e^{F(x)}n!∗[xn]eF(x)
这里n!n!n!乘的是里面的EGFEGFEGF,而外面eF(x)=∑F(x)ii!e^{F(x)}=\sum \frac{F(x)^i}{i!}eF(x)=∑i!F(x)i,除i!i!i!是为了避免选取的iii个被重复计算i!i!i!次
显然,不好推
考虑g(x)g(x)g(x)为∑x+y=n(nx)3xy\sum_{x+y=n}{n\choose x}3^{xy}∑x+y=n(xn)3xy的生成函数,其EGF为G(x)G(x)G(x),这样是不考虑这一块是否联通的,那么如果这里有k个联通快,由于左右两部可以互换,重复算了2k2^k2k次,有关系式G(x)=∑F(x)i2ii!=e2F(x)G(x)=\sum \frac{F(x)^i2^i}{i!}=e^{2F(x)}G(x)=∑i!F(x)i2i=e2F(x),那么eF(x)=G(x)e^{F(x)}=\sqrt{G(x)}eF(x)=G(x)
Part 1
如何求G(x)呢
二次剩余??很遗憾3在摸998244353下无二次剩余。。。
[xn]G(x)=∑i+j=n(ni)3ijn!=3n22∗∑i+j=n3−i22i!×3−j22j!
\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)(mod  xn2)G(x)^2\equiv A(x)(\mod x^\frac n2)G(x)2≡A(x)(modx2n)
B(x)2≡A(x)(mod  xn)B(x)^2\equiv A(x)(\mod x^n)B(x)2≡A(x)(modxn)
这时
B(x)−G(x)≡0(mod  xn2)(B(x)−G(x))2≡0(mod  xn)B2(x)−2B(x)G(x)+G2(x)≡0(mod  xn)A(x)−2B(x)G(x)+G2(x)≡0(mod  xn)B(x)≡G(x)2+A(x)2G(x)(mod  xn)
\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,比较特殊
不然用二次剩余具体是这样:
勒让德符号(np)(\frac np)(pn)
(np)=np−12={1,存在二次剩余0,n=0−1,不存在二次剩余(mod  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有实根
要找a2=n(mod  p)a^2=n(\mod p)a2=n(modp),先随机一个(t2−np)=−1(\frac{t^2-n}p)=-1(pt2−n)=−1,令w=t2−n(可以看作是复数根)w=\sqrt{t^2-n}(可以看作是复数根)w=t2−n(可以看作是复数根),那么a=(1−w)p+12(显然这个只有实部)a=(1-w)^\frac{p+1}2(显然这个只有实部)a=(1−w)2p+1(显然这个只有实部)
Part 3
如何去求A(x)2G(x)\frac{A(x)}{2G(x)}2G(x)A(x)?考虑求1G(x)\frac 1{G(x)}G(x)1
多项式求逆!
同开根的思路
设
B(x)A(x)≡1(mod  xn)B(x)A(x)\equiv 1(\mod x^n)B(x)A(x)≡1(modxn)
G(x)A(x)≡1(mod  xn2)G(x)A(x)\equiv 1(\mod x^\frac n2)G(x)A(x)≡1(modx2n)
同理
B(x)−G(x)≡0(mod  xn2)(B(x)−G(x))2≡0(mod  xn)B2(x)−2B(x)G(x)+G2(x)≡0(mod  xn)B(x)−2G(x)+G2(x)A(x)≡0(mod  xn)B(x)≡2G(x)−A(x)G2(x)(mod  xn)
\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−2nn-2nn−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);
}