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;
}