[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]);
}
posted @ 2021-01-13 20:41  fhq_treap  阅读(103)  评论(0编辑  收藏  举报