您的位置:首页 > 其它

BZOJ 2729 [HNOI2012]排队

2012-05-04 15:45 295 查看
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2729

题目大意: n 名男同学,m 名女同学和两名老师排队,并且任意两名女同学不能相邻,两名老师也不能相邻,求方案数。

分析:赤果果的排列组合嘛,不会就去问数学老师吧。

盗图一张:

View Code

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
using namespace std;
#define MaxL 2000
const long long MOD=1000000000;
struct Bignum
{
int len;
long long a[MaxL];
void init()
{

}
Bignum()
{
len=0;
memset(a,0,sizeof(a));
}
};

int n,m;
Bignum ans1,ans2;

void operator *= (Bignum &p,int x)
{
int tmp=0;
for (int i=1;i<=p.len;++i)
{
p.a[i]=p.a[i]*x+tmp;
tmp=p.a[i]/MOD;
p.a[i]%=MOD;
}
if (tmp)
p.a[++p.len]=tmp;
}

Bignum operator + (Bignum x,Bignum y)
{
int len=max(x.len,y.len);
int tmp=0;
for (int i=1;i<=len;++i)
{
x.a[i]=x.a[i]+y.a[i]+tmp;
tmp=x.a[i]/MOD;
x.a[i]%=MOD;
}
x.len=len;
if (tmp)
x.a[++x.len]=tmp;
return x;
}

Bignum operator * (Bignum x,Bignum y)
{
Bignum p;
p.len=0;
for (int i=1;i<MaxL;++i)
p.a[i]=0;
for (int i=1;i<=x.len;++i)
{
int tmp=0;
for (int j=1;j<=y.len;++j)
{
p.a[i+j-1]=p.a[i+j-1]+x.a[i]*y.a[j]+tmp;
tmp=p.a[i+j-1]/MOD;
p.a[i+j-1]%=MOD;
}
if (tmp)
p.a[i+y.len]+=tmp;
}
int tmp=0;
for (int i=1;i<MaxL;++i)
{
p.a[i]=p.a[i]+tmp;
tmp=p.a[i]/MOD;
p.a[i]%=MOD;
}
for (int i=MaxL-1;i>=1;--i)
if (p.a[i])
{
p.len=i;
break;
}
if (!p.len) p.len=1;
return p;
}

void write(Bignum p)
{

printf("%lld",p.a[p.len]);
for (int i=p.len-1;i>=1;--i)
printf("%09lld",p.a[i]);
printf("\n");
}

Bignum A(int n,int m)
{
Bignum p;
p.len=1;
p.a[1]=1;
for (int i=0;i<m;++i)
p*=(n-i);
return p;
}

int main()
{
scanf("%d%d",&n,&m);
if (n>=1 && n+3>=m)
{
ans1=A(n+3,m);
ans1*=((n+1)*n);
}
if (m>=1 && n+3>=m)
{
ans2=A(n+2,m-1);
ans2*=(2*(n+1)*m);
}
write(A(n,n)*(ans1+ans2));
return 0;
}


写这个题是现学的高精乘高精啊...
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: