CF1768E Partial Sorting
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; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具