冷静一下我们知道加强版常数上是不允许任何类型的牛顿迭代出现的,目前知道以下两种思路上不同的做法。
首先不难发现每行都必须有两个石子,所以讨论的重点肯定在列上面。
行当做一个点集,列当做一个点集,每个位置放的石子视为一条行向列连出的边。
不难发现这玩意是个二分图,设左边有 n n n 个二度点,右边有 k k k 个二度点和 2 ( n − k ) 2(n-k) 2(n−k) 个一度点,需要统计合法的连边方案数 S k S_k Sk。
将每个二度点拆开为一度点,连边之后复原,不难发现会有一些边本来连的就是二度点,被缩为重边,枚举重边至少的数量进行容斥。
S k = 1 2 n + k ∑ i = 0 k ( − 1 ) i ( n i ) ( k i ) i ! 2 i ( 2 n − 2 i ) ! S_k=\frac{1}{2^{n+k}}\sum_{i=0}^k(-1)^i{n\choose i}{k\choose i}i!2^i(2n-2i)! Sk=2n+k1i=0∑k(−1)i(in)(ik)i!2i(2n−2i)!
可以构造卷积算一算。
答案即为: A n s = ∑ k = 0 n ( m 2 n − k ) ( 2 n − k k ) S k Ans=\sum_{k=0}^n{m\choose 2n-k}{2n-k\choose k}S_k Ans=k=0∑n(2n−km)(k2n−k)Sk统计一下即可。
考虑把列当做点集,行当做边集,同一行的两个石子当做一条边,不难发现可以视为图计数,只不过边带上了标号。
发现这个图只会有这几种联通块:1) 点数不小于2的环,2)点数不小于2的链 ,3)孤立点。
设 F ( x ) F(x) F(x) 为链的 E G F EGF EGF, G ( x ) G(x) G(x) 为环的 E G F EGF EGF。
F ( x ) = ∑ i ≥ 2 x i 2 G ( x ) = ∑ i ≥ 2 x i 2 i F(x)=\sum_{i\geq 2}\frac{x^i}{2}\\G(x)=\sum_{i\geq 2}\frac{x^i}{2i} F(x)=i≥2∑2xiG(x)=i≥2∑2ixi
考虑枚举链的个数进行统计,链数为 i i i 的时候总点数为 n + i n+i n+i。
A n s = ∑ i = 0 n n ! ( n + i ) ! ⋅ ( m n + i ) [ x n + i ] ( e G ( x ) F ( x ) i / i ! ) Ans=\sum_{i=0}^nn!(n+i)!\cdot {m\choose n+i}[x^{n+i}](e^{G(x)}F(x)^i/i!) Ans=i=0∑nn!(n+i)!⋅(n+im)[xn+i](eG(x)F(x)i/i!)
简单转化可以得到:
A n s = n ! m n ‾ [ x n ] ( e G ( x ) ( ∑ i = 0 n F ( x ) i i ! x i ⋅ ( m − n ) i ‾ ) ) Ans=n!m^{\underline n}[x^n](e^{G(x)}(\sum_{i=0}^n\frac{F(x)^i}{i!x^i}\cdot (m-n)^{\underline i})) Ans=n!mn[xn](eG(x)(i=0∑ni!xiF(x)i⋅(m−n)i))
首先 e G ( x ) e^{G(x)} eG(x) 是不能用牛顿迭代做的。。。
考虑实际意义,进行DP。设 g i g_i gi 表示点数为 i i i 的图的数量除掉 i ! i! i! 的值,每个连通块都是点数不小于2的环,枚举 1 1 1 号点所在连通块大小。我们得到 g i i ! = ∑ j = 2 i ( j − 1 ) ! 2 ( i − 1 j − 1 ) g i − j ( i − j ) ! g i = 1 2 i ∑ j = 2 i g i − j g_ii!=\sum_{j=2}^i\frac{(j-1)!}{2}{i-1\choose j-1}g_{i-j}(i-j)!\\ g_i=\frac{1}{2i}\sum_{j=2}^ig_{i-j} gii!=j=2∑i2(j−1)!(j−1i−1)gi−j(i−j)!gi=2i1j=2∑igi−j
从某种意义上来说这个式子还挺美妙的,于是可以维护前缀和把 e G ( x ) e^{G(x)} eG(x) 推出来了。
还剩下一个部分 : H ( x ) = ∑ i = 0 n ( F ( x ) / x ) i i ! ⋅ ( m − n ) i ‾ H(x)=\sum_{i=0}^n\frac{(F(x)/x)^i}{i!}\cdot (m-n)^{\underline i} H(x)=∑i=0ni!(F(x)/x)i⋅(m−n)i
不难发现 [ x t ] ( F ( x ) / x ) i = [ x t ] ( x 2 ( 1 − x ) ) i = 1 2 i ( t − 1 i − 1 ) [x^t](F(x)/x)^i=[x^t](\frac{x}{2(1-x)})^i=\frac{1}{2^i}{t-1\choose i-1} [xt](F(x)/x)i=[xt](2(1−x)x)i=2i1(i−1t−1)
卷积算出 H ( x ) H(x) H(x) 然后算出 exp ( G ( x ) ) \exp(G(x)) exp(G(x)),由于只需要取第 n n n 项,随便扫一下就行了
代码:
#include
#define ll long long
#define re register
#define cs const
using std::cerr;
using std::cout;
cs int mod=943718401;
inline int add(int a,int b){return a+b>=mod?a+b-mod:a+b;}
inline int dec(int a,int b){return a-b<0?a-b+mod:a-b;}
inline int mul(int a,int b){ll r=(ll)a*b;return r>=mod?r%mod:r;}
inline void Inc(int &a,int b){a+=b-mod;a+=a>>31&mod;}
inline void Dec(int &a,int b){a-=b;a+=a>>31&mod;}
inline void Mul(int &a,int b){a=mul(a,b);}
inline int po(int a,int b){int r=1;for(;b;b>>=1,Mul(a,a))if(b&1)Mul(r,a);return r;}
inline void ex_gcd(int a,int b,int &x,int &y){
if(!b){x=1,y=0;return ;}ex_gcd(b,a%b,y,x);y-=a/b*x;
}inline int Inv(int a){static int x,y;ex_gcd(mod,a,y,x);return x+(x>>31&mod);}
cs int bit=22,SIZE=1<<bit|7;
int r[SIZE],*w[bit+1];
int len,inv_len;
void init_len(int deg){
int lm;
for(len=1,lm=1;len<deg;len<<=1,++lm);
inv_len=Inv(len);--lm;
for(int re i=1;i<len;++i)
r[i]=r[i>>1]>>1|((i&1)?len>>1:0);
for(int re i=1;i<=lm;++i)
w[i]=new int[1<<(i-1)];
int wn=po(7,(mod-1)>>lm);w[lm][0]=1;
for(int re i=1;i<(1<<(lm-1));++i)
w[lm][i]=mul(w[lm][i-1],wn);
for(int re i=lm-1;i;--i)
for(int re j=0;j<(1<<(i-1));++j)
w[i][j]=w[i+1][j<<1];
}void DFT(int *A){
for(int re i=1;i<len;++i)
if(i<r[i])std::swap(A[i],A[r[i]]);
for(int re i=1,d=1;i<len;i<<=1,++d)
for(int re j=0;j<len;j+=i<<1)
for(int re k=0;k<i;++k){
int &t1=A[j+k],&t2=A[i+j+k];
int t=mul(t2,w[d][k]);
t2=dec(t1,t);Inc(t1,t);
}
}void IDFT(int *A){
DFT(A);std::reverse(A+1,A+len);
for(int re i=0;i<len;++i)
Mul(A[i],inv_len);
}
cs int N=2e6+7;
int n,m,pw[N+N],ipw[N+N];ll x;
int A[SIZE],B[SIZE],dn[N+N];
int fac[N+N],_fac[N+N];
inline int C(int n,int m){
return n>=m&&m>=0?mul(fac[n],mul(_fac[m],_fac[n-m])):0;
}
void Main(){
scanf("%d%lld",&n,&x);
int ans=0;m=x%mod;
for(int re i=pw[0]=1;i<=n+n;++i)
pw[i]=add(pw[i-1],pw[i-1]);
int i2=(mod+1)/2;
for(int re i=ipw[0]=1;i<=n+n;++i)
ipw[i]=mul(ipw[i-1],i2);
for(int re i=fac[0]=1;i<=n+n;++i)
fac[i]=mul(fac[i-1],i);
_fac[n+n]=Inv(fac[n+n]);
for(int re i=n+n;i;--i)
_fac[i-1]=mul(_fac[i],i);
for(int re i=0;i<=n;++i){
A[i]=mul(C(n,i),pw[i]);
Mul(A[i],fac[2*(n-i)]);
if(i&1)A[i]=mod-A[i];
B[i]=_fac[i];
}init_len(n+n+1);
DFT(A);DFT(B);
for(int re i=0;i<len;++i)
Mul(A[i],B[i]);
IDFT(A);dn[0]=1;
for(int re i=1;i<=n+n;++i)
dn[i]=mul(dn[i-1],m-i+1);
for(int re k=0;k<=n;++k){
int val=mul(mul(fac[k],ipw[n+k]),A[k]);
Inc(ans,mul(mul(dn[n+n-k],val),mul(_fac[k],_fac[2*(n-k)])));
}cout<<ans<<"\n";
}
inline void file(){
#ifdef zxyoi
freopen("ishi.in","r",stdin);
#endif
}signed main(){file();Main();return 0;}
#include
#define ll long long
#define re register
#define cs const
using std::cerr;
using std::cout;
cs int mod=943718401;
inline int add(int a,int b){return a+b>=mod?a+b-mod:a+b;}
inline int dec(int a,int b){return a-b<0?a-b+mod:a-b;}
inline int mul(int a,int b){ll r=(ll)a*b;return r>=mod?r%mod:r;}
inline void Inc(int &a,int b){a+=b-mod;a+=a>>31&mod;}
inline void Dec(int &a,int b){a-=b;a+=a>>31&mod;}
inline void Mul(int &a,int b){a=mul(a,b);}
inline int po(int a,int b){int r=1;for(;b;b>>=1,Mul(a,a))if(b&1)Mul(r,a);return r;}
inline void ex_gcd(int a,int b,int &x,int &y){
if(!b){x=1,y=0;return ;}ex_gcd(b,a%b,y,x);y-=a/b*x;
}inline int Inv(int a){static int x,y;ex_gcd(mod,a,y,x);return x+(x>>31&mod);}
cs int bit=22,SIZE=1<<bit|7;
int r[SIZE],*w[bit+1];
int len,inv_len;
void init_len(int deg){
int lm;
for(len=1,lm=1;len<deg;len<<=1,++lm);
inv_len=Inv(len);--lm;
for(int re i=1;i<len;++i)
r[i]=r[i>>1]>>1|((i&1)?len>>1:0);
for(int re i=1;i<=lm;++i)
w[i]=new int[1<<(i-1)];
int wn=po(7,(mod-1)>>lm);w[lm][0]=1;
for(int re i=1;i<(1<<(lm-1));++i)
w[lm][i]=mul(w[lm][i-1],wn);
for(int re i=lm-1;i;--i)
for(int re j=0;j<(1<<(i-1));++j)
w[i][j]=w[i+1][j<<1];
}void DFT(int *A){
for(int re i=1;i<len;++i)
if(i<r[i])std::swap(A[i],A[r[i]]);
for(int re i=1,d=1;i<len;i<<=1,++d)
for(int re j=0;j<len;j+=i<<1)
for(int re k=0;k<i;++k){
int &t1=A[j+k],&t2=A[i+j+k];
int t=mul(t2,w[d][k]);
t2=dec(t1,t);Inc(t1,t);
}
}void IDFT(int *A){
DFT(A);std::reverse(A+1,A+len);
for(int re i=0;i<len;++i)
Mul(A[i],inv_len);
}
cs int N=2e6+7;
int n,m,ipw[N];ll x;
int A[SIZE],B[SIZE],dn[N];
int fac[N],_fac[N],inv[N];
inline int C(int n,int m){
return n>=m&&m>=0?mul(fac[n],mul(_fac[m],_fac[n-m])):0;
}
void Main(){
scanf("%d%lld",&n,&x);
int ans=0;m=x%mod;
int i2=(mod+1)/2;
for(int re i=ipw[0]=1;i<=n;++i)
ipw[i]=mul(ipw[i-1],i2);
for(int re i=fac[0]=1;i<=n;++i)
fac[i]=mul(fac[i-1],i);
_fac[n]=Inv(fac[n]);
for(int re i=n;i;--i)
_fac[i-1]=mul(_fac[i],i);
for(int re i=dn[0]=1;i<=n;++i)
dn[i]=mul(dn[i-1],dec(m+1,n+i));
for(int re i=0;i<=n;++i){
A[i]=i?mul(mul(_fac[i],_fac[i-1]),mul(dn[i],ipw[i])):0;
B[i]=_fac[i];
}inv[0]=inv[1]=1;
for(int re i=2;i<=n;++i)
inv[i]=mul(inv[mod%i],mod-mod/i);
init_len(n+n+1);DFT(A),DFT(B);
for(int re i=0;i<len;++i)
Mul(A[i],B[i]);
IDFT(A),A[0]=1;
B[0]=1,B[1]=0;
for(int i=2,sm=1;i<=n;++i){
B[i]=mul(mul(i2,inv[i]),sm);
Inc(sm,B[i-1]);
}for(int re i=0;i<=n;++i)
Inc(ans,mul(mul(A[i],i?fac[i-1]:1),B[n-i]));
Mul(ans,fac[n]);
for(int re i=m;i>m-n;--i)
Mul(ans,i);
cout<<ans<<"\n";
}
inline void file(){
#ifdef zxyoi
freopen("ishi.in","r",stdin);
#endif
}signed main(){file();Main();return 0;}