codevs 1994 排队 排列组合+高精度

/*
数学题0.0
最后答案:A(n,n)*A(n+1,2)*A(n+3,m)+A(n,n)*C(m,1)*A(2,2)*C(n+1,1)*A(n+2,m-1);
简单解释一下 
+之前的很显然 先排男生 然后老师插空 然后女生插空 显然符合条件
但仔细一想会发现少算了一部分 就是 老师 女生 老师 的情况
在单独考虑着一种 先选夹在中间的女生(C(m,1)) 然后老师换位置 A(2,2) 
然后安排这个(C(n+1,1)) 然后剩下的女生插空 
注意不能把  老师 女生 老师  和其他女生看成一样的 因为这个具有特殊性 
然后就是高精了 最简单的 连压位都不用 
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#define ll long long
using namespace std;
int n,m,a[1000010],b[1000010],c[1000010],ans[10000010],l1,l2,l;
void get_na()
{
    for(int i=2;i<=n;i++)
      {
          for(int j=1;j<=l1;j++)
            a[j]=a[j]*i;
          for(int j=1;j<=l1;j++)
            if(a[j]>=10)
              {
                a[j+1]+=a[j]/10;
              a[j]=a[j]%10;
            }
        while(a[l1+1])
          {
              l1++;
              a[l1+1]+=a[l1]/10;
              a[l1]=a[l1]%10;
          }
      }
}
void get_nb()
{
    for(int i=1;i<=l1;i++)
      b[i]=a[i];
    l2=l1;
}
void Mul1(int x)
{
    for(int i=1;i<=l1;i++)
            a[i]=a[i]*x;
          for(int i=1;i<=l1;i++)
            if(a[i]>=10)
              {
                a[i+1]+=a[i]/10;
              a[i]=a[i]%10;
            }
        while(a[l1+1])
          {
              l1++;
              a[l1+1]+=a[l1]/10;
              a[l1]=a[l1]%10;
          }
}
void Mul2(int x)
{
    for(int i=1;i<=l2;i++)
            b[i]=b[i]*x;
          for(int i=1;i<=l2;i++)
            if(b[i]>=10)
              {
                b[i+1]+=b[i]/10;
              b[i]=b[i]%10;
            }
        while(b[l2+1])
          {
              l2++;
              b[l2+1]+=b[l2]/10;
              b[l2]=b[l2]%10;
          }
}
void Add()
{
    l=max(l1,l2);
    for(int i=1;i<=l;i++)
      c[i]=a[i]+b[i];
    for(int i=1;i<=l;i++)
      if(c[i]>9)
        {
          c[i+1]++;c[i]=c[i]%10;
        }
    while(c[l+1])l++;
}
int main()
{
    scanf("%d%d",&n,&m);
    a[1]=1;l1=1;
    b[1]=1;l2=1;
    get_na();
    get_nb();
    Mul1(n);
    Mul1(n+1);
    for(int i=n+3;i>=n+3-m+1;i--)
      Mul1(i);
    Mul2(2*m);
    Mul2(n+1);
    for(int i=n+2;i>=n+2-m+1+1;i--)
      Mul2(i);
    Add();
    for(int i=l;i>=1;i--)
      printf("%d",c[i]);
    return 0;
}
原文地址:https://www.cnblogs.com/yanlifneg/p/5524690.html