CF1768E Partial Sorting
jiangtaizhe001 · · 题解
可能更好的阅读体验
题目传送门
题目翻译
UPD:组合数上下打反了 /youl,已经更正。
题目解析
显然我们可以证明
如果前面交换一次,那么有
考虑交换前后都可以的重复情况,那么就是
容斥得
考虑
如果前面交换一次然后后面交换,那么只需要保证
如果是先交换后面同理。
考虑重复的情况,也就是
枚举
所以
答案就是
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;
}