[HNOI2012]排队
题意
有\(n\)个男生,\(m\)个女生,\(2\)个老师
要求女生不相邻,老师不相邻,问这样的方案数
想法
首先因为老师的数量比较少,我们从老师来分类
首先两个老师之间存在一个男生
这种情况下我们先对男生进行排列\(A^n_n\)
再插空两个老师\(A^n_n\ A_{n + 1}^2\)
在插空\(m\)个女生\(A^n_n\ A_{n + 1}^2\ A_{n + 3}^m\)
首先两个老师之间只存在一个女生
那么我们把老师进行捆绑\(A_2^2\)
然后先选定这个在老师之间的女生\(m * A_2^2\)
然后对男生排列\(A^n_n\)
然后把老师女生老师这个整体插空\(A^n_n\ *(n + 1)\ *\ m\ *\ A_2^2\)
再把女生插空\(A^n_n\ A_2^2\ A_{n + 2}^{m - 1}\ *\ m\ *\ (n + 1)\)
然后化简一下柿子
这里是高精乘低精那就很好搞了
压位就行了
代码
#include<iostream>
#include<cstdio>
#define ll long long
ll n,m,len = 1;
const long long p=10000000000ll;
ll ans[10000];
void mul(int x){
ll pre = 0,tem;
for(int i = 1;i <= len;++i){
tem = ans[i] * x;
ans[i] = tem % p + pre;
pre = tem / p;
}
if(pre)ans[++len] = pre;
}
int main(){
scanf("%lld%lld",&n,&m);
ans[1] = 1;
mul(n + 1);
mul(n * (n + 3) + 2 * m);
for(int i = 1;i <= n;++i)mul(i);
for(int i = n - m + 4;i <= n + 2;++i)mul(i);
std::cout<<ans[len];
while(--len)
printf("%0*lld",10,ans[len]);
}