N 個點,紅/黑兩色。任意三點形成三角形,同色三角形指三頂點同色。總三角形數 C(N,3)。求同色三角形數 = 總數 - 非同色數。
設點 i 連接紅點 R_i 個、黑點 B_i 個。非同色三角形每條「異色邊」被計算兩次(兩端點各一次),故:
非同色數 = Σ(R_i × B_i) / 2
「異色」定義為 gcd(x,y) > 1(非互質)。需對每個點 i,統計與它互質/不互質的點數。N≤10^5,暴力 O(N^2) 不可行。
v 的倍數個數 = Σ μ(d) * cnt[d] (d|v)cnt[d]:值為 d 的倍數的點數// 預處理質因子
for (int i=2; i<=MAX; i++) if (!vis[i]) {
primes.push_back(i);
for (int j=i; j<=MAX; j+=i) { vis[j]=1; fac[j].push_back(i); }
}
// 遍歷點計算答案
for (int i=1; i<=n; i++) {
int v = a[i];
// 利用容斥計算與 v 不互質的已處理點數
int not_coprime = 0;
for (int mask=1; mask < (1<>k&1) { d*=fac[v][k]; bits++; }
not_coprime += (bits&1 ? 1 : -1) * cnt[d];
}
int coprime = processed - not_coprime;
// 更新答案...
for (int d : divisors[v]) cnt[d]++; // 更新倍數計數
processed++;
}