题目解析
显然我们可以证明 \(f(p)\in\{0,1,2,3\}\)
\(f(p)=0\) 显然只有 \(s_1=1\) 种。
考虑 \(f(p)=1\)
如果前面交换一次,那么有 \((2n)!\) 种。只交换后面同理。
考虑交换前后都可以的重复情况,那么就是 \(n!\) 种。
容斥得 \(s_2=2\times(2n)!-n!\)
考虑 \(f(p)=2\)
如果前面交换一次然后后面交换,那么只需要保证 \(1\sim n\) 全部在 \(1\sim 2n\) 位置内。方案数是
如果是先交换后面同理。
考虑重复的情况,也就是 \(1\sim n\) 全部在 \(1\sim 2n\) 位置,并且 \(2n+1\sim 3n\) 全部在 \(n+1\sim 3n\) 位置。
枚举 \(1\sim n\) 在 \(n+1\sim 2n\) 位置内的数量,可以得到重复的方案为
所以
\[s_3=2\times\binom{n}{2n}\times(2n)!-M \]\(f(p)=3\) 直接用来减就好了,\(s_4=(3n)!-s_1-s_2-s_3\)
答案就是 \(s_2+2s_3=3s_4\)
int n,MOD; ll fact[maxn],inv[maxn],s1,s2,s3,s4,M;
ll fastpow(ll x,ll y){
ll tmp=x%MOD,res=1;
while(y){
if(y&1) res=res*tmp%MOD;
y>>=1; tmp=tmp*tmp%MOD;
} return res;
}
#define P(n,m) (fact[n]*inv[(n)-(m)]%MOD)
#define C(n,m) (fact[n]*inv[m]%MOD*inv[(n)-(m)]%MOD)
int main(){
n=read(); MOD=read(); int i; fact[0]=1; for(i=1;i<=n*3;i++) fact[i]=fact[i-1]*i%MOD;
inv[2*n]=fastpow(fact[2*n],MOD-2); for(i=n*2-1;i>=0;i--) inv[i]=inv[i+1]*(i+1)%MOD;
s1=1; s2=2*fact[2*n]-fact[n]+MOD-1; s2%=MOD;
M=0; for(i=0;i<=n;i++) M+=C(n,i)*C(n,n-i)%MOD*P(2*n-i,n)%MOD,M%=MOD;
M*=fact[n]*fact[n]%MOD,M%=MOD;
s3=2*P(2*n,n)*fact[2*n]%MOD-M-(s1+s2); s3%=MOD,s3+=MOD,s3%=MOD;
s4=fact[3*n]-s1-s2-s3; s4%=MOD,s4+=MOD,s4%=MOD;
print((s2+s3*2+s4*3)%MOD); return 0;
}
标签:Sorting,Partial,inv,CF1768E,fact,2n,ll,sim,MOD
From: https://www.cnblogs.com/jiangtaizhe001/p/17044655.html