UVA

来源:互联网 发布:通讯录恢复软件 编辑:程序博客网 时间:2024/06/07 19:50

polya定理

注:calcul函数一定情况下可通用。

#include"bits/stdc++.h"using namespace std;typedef unsigned long long LL;int sum,a[3],b[3];LL c[41][41];int gcd(int a,int b){    if(b == 0) return a;    return gcd(b,a%b);}void init(){    int n=40;    c[0][0] = c[1][0] = c[1][1] = 1;    for(int i = 2; i <= n; i++){        c[i][0] = 1;        for(int j = 1; j <= i; j++){            c[i][j] = c[i-1][j-1]+c[i-1][j];        }    }}LL calcul(int m){    int n = 0;    LL ret= 1;    for(int i = 0; i < 3; i++){        if(b[i]%m != 0)            return 0;        b[i]/=m;        n += b[i];    }    for(int i = 0; i < 3; i++){        ret *= c[n][b[i]];        n -= b[i];    }    return ret;}LL work(){    LL ret = 0;    for(int i = 1; i <= sum; i++){        memcpy(b,a,sizeof(b));        ret += calcul(sum/gcd(sum,i));    }    return ret;}LL work1(){    LL ret = 0;    for(int i = 0; i < 3; i++){        memcpy(b,a,sizeof(a));        b[i]--;        if(b[i] < 0) continue;        ret += sum*calcul(2);    }    return ret;}LL work2(){    LL ret = 0;    for(int i = 0; i < 3; i++){        for(int j = 0; j < 3; j++){            memcpy(b,a,sizeof(b));            b[i]--; b[j]--;            if(b[i] < 0 || b[j] < 0) continue;            ret += sum/2*calcul(2);        }    }    memcpy(b,a,sizeof(b));    ret += sum/2*calcul(2);    return ret;}void solve(){    LL ans = work();    if(sum&1) ans += work1();    else ans += work2();    printf("%lld\n",ans/(sum*2));}int main(){    int T;    init();    scanf("%d",&T);    while(T--){        sum = 0;        memset(a,0,sizeof(a));        for(int i = 0; i < 3; i++){            scanf("%d",&a[i]);            sum += a[i];        }        solve();    }    return 0;}

原创粉丝点击