bzoj2729: [HNOI2012]排队

高精度+排列组合。

如果计算老师能挨在一起的情况 有 (n+2)! * A(n+3,m)

老师一定挨宰一起的情况 有 2*(n+1)!*A(n+2,m)。

相减就是答案。

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn = 3000;
const int mod = 10000;

struct bigint { 
    int a[maxn+10];
    
    int& operator[] (int x) {
        return a[x];    
    }
    
    bigint operator * (int x) {
        bigint c;
        for(int i=1;i<=maxn;i++) {
            c[i]+=a[i]*x;
            c[i+1]+=c[i]/mod;
            c[i]=c[i]%mod;
        }
        return c;
    }
    
    bigint operator - (bigint b) {
        bigint c;
        for(int i=1;i<=maxn;i++) {
            c[i]+=a[i]-b[i];
            if(c[i]<0) {c[i]+=mod; c[i+1]--;}
        }
        return c;
    }
    
    void print() {
        int k;
        for(k=maxn;k>=1;k--) if(a[k]) break;
        printf("%d",a[k]);
        for(int i=k-1;i>=1;i--) printf("%04d",a[i]);    
        printf("\n");
    }
    
    bigint() {
        memset(a,0,sizeof(a));    
    }
}t1,t2;

int n,m;

int main() {
    scanf("%d%d",&n,&m);    
    t1[1]=1; t2[1]=2;
    for(int i=1;i<=n+2;i++) t1=t1*i;
    for(int i=n+4-m;i<=n+3;i++) t1=t1*i;
    for(int i=1;i<=n+1;i++) t2=t2*i;
    for(int i=n+3-m;i<=n+2;i++) t2=t2*i;
    t1=t1-t2;
    t1.print();
    return 0;
}
posted @ 2016-07-04 01:14  invoid  阅读(171)  评论(0编辑  收藏  举报