[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]);
}
原文地址:https://www.cnblogs.com/dixiao/p/14274340.html