You are given a rectangular parallelepiped with sides of positive integer lengths AA, BB and CC.
Find the number of different groups of three integers (aa, bb, cc) such that 1≤a≤b≤c1≤a≤b≤c and parallelepiped A×B×CA×B×C can be paved with parallelepipeds a×b×ca×b×c. Note, that all small parallelepipeds have to be rotated in the same direction.
For example, parallelepiped 1×5×61×5×6 can be divided into parallelepipeds 1×3×51×3×5, but can not be divided into parallelepipeds 1×2×31×2×3.
The first line contains a single integer tt (1≤t≤1051≤t≤105) — the number of test cases.
Each of the next tt lines contains three integers AA, BB and CC (1≤A,B,C≤1051≤A,B,C≤105) — the sizes of the parallelepiped.
For each test case, print the number of different groups of three points that satisfy all given conditions.
4
1 1 1
1 6 1
2 2 2
100 100 100
1
4
4
165
In the first test case, rectangular parallelepiped (1,1,1)(1,1,1) can be only divided into rectangular parallelepiped with sizes (1,1,1)(1,1,1).
In the second test case, rectangular parallelepiped (1,6,1)(1,6,1) can be divided into rectangular parallelepipeds with sizes (1,1,1)(1,1,1), (1,1,2)(1,1,2), (1,1,3)(1,1,3) and (1,1,6)(1,1,6).
In the third test case, rectangular parallelepiped (2,2,2)(2,2,2) can be divided into rectangular parallelepipeds with sizes (1,1,1)(1,1,1), (1,1,2)(1,1,2), (1,2,2)(1,2,2) and (2,2,2)(2,2,2).
这题目其实求的就是a的因子乘b的因子乘c的因子
所以重点是算出a,b,c的因子
但是中间会出现重复的情况,比如(1,1,2),(1,2,1)是同一种情况
所以我们还要用容斥原理去掉这种情况
情况分为四种:a,b重负的情况;a,c重复的情况;b,c重复的情况;a,b,c重复的情况
#include <map> #include <set> #include <stack> #include <cmath> #include <queue> #include <cstdio> #include <vector> #include <string> #include <cstring> #include <iostream> #include <algorithm> #define A 0 #define B 1 #define C 2 #define AB 3 #define BC 4 #define AC 5 #define ABC 6 #define debug(a) cout << #a << " " << a << endl using namespace std; const int maxn = 1e5; const int mod = 10000007; typedef long long ll; ll t, a, b, c, kt[5],p[10], nu[maxn+10], num[maxn+10]; ll gcd( ll a, ll b) { return b==0?a:gcd(b,a%b); } map<ll,ll>mm; vector<ll> va, vb, vc; void init() { //预处理每个数因子的数量 for( ll i = 1; i <= maxn; i ++ ) { for( ll j = i; j <= maxn; j +=i ) { nu[j] ++; } } va.push_back(A); va.push_back(AB); va.push_back(AC); va.push_back(ABC); vb.push_back(B); vb.push_back(AB); vb.push_back(BC); vb.push_back(ABC); vc.push_back(C); vc.push_back(AC); vc.push_back(BC); vc.push_back(ABC); } ll cal3( ll x) { ll res = 0; res += x + x*(x-1) + x*(x-1)*(x-2)/6;//三部分取相同,两部分取相同,三部分都不同 return res; } ll cal2( ll x ) { ll res = 0; res += x + x*(x-1)/2;//两部分相同,两部分不同 return res; } int main() { init(); cin >> t; while(t--) { cin >> a >> b >> c; ll ab = gcd(a,b), bc = gcd(b,c), ac = gcd(a,c); ll abc = gcd(ab,c); ll nABC = nu[abc]; ll nAB = nu[ab] - nABC, nBC = nu[bc] - nABC, nAC = nu[ac] - nABC; ll nA = nu[a] - nAB - nAC - nABC, nB = nu[b] - nAB - nBC - nABC; ll nC = nu[c] - nAC - nBC - nABC; num[ABC] = nABC; num[AB] = nAB, num[AC] = nAC, num[BC] = nBC; num[A] = nA, num[B] = nB, num[C] = nC; ll ans = 0; mm.clear(); for( ll i = 0; i < va.size(); i ++ ) { for( ll j = 0; j < vb.size(); j ++ ) { for( ll k = 0; k < vc.size(); k ++ ) { kt[0] = va[i], kt[1] = vb[j], kt[2] = vc[k]; sort( kt, kt+3 ); ll x = kt[0], y = kt[1], z = kt[2]; ll tmp = 0; for( ll l = 0; l < 3; l ++ ) { tmp=1ll*tmp*maxn+1ll*kt[l]; } if( mm[tmp] ) continue;///打标记去重 mm[tmp] = 1; if( x == y && y == z ) ans += cal3(num[x]); else if( x == y ) ans += num[z]*cal2(num[x]); else if( y == z ) ans += num[x]*cal2(num[y]); else ans += num[x]*num[y]*num[z]; } } } cout << ans << endl; } return 0; }