Http://acm.hdu.edu.cn/showproblem.php? PID = 1, 5072
Monochrome triangle Model
I spent three hours on the competition with my teammates and finally found that I wanted to go off. I feel a pity. If you know this model, you can easily get the silver...
The number of triangles in the same color is not repeated. The total number of triangles is C (n, 3). You only need to subtract triangles of different colors. For each vertex (number), the red edge that interacts with each other and the blue edge that does not interact with each other, the number of triangles of different colors for this vertex is the number of blue edges * Number of red edges/2, because the same triangle is calculated twice. The number of triangles in the same color is C (n, 3)-Σ number of blue edges * Number of red edges/2.
We only need to find the number of the blue edge to know the number of the red edge. How can we find the number of different numbers from the number? First, the original several quality factors are decomposed, and all the combinations of these quality factors are enumerated. Each quality factor can be used at most once. Then, the combination of several quality factors is ansnum, observe the number of quality factors of ansnum Based on the refresh principle. If it is an odd number, add the number of all the numbers that can be integers of ansnum. Otherwise, subtract the number. In this way, the number of blue edges is known.
# Include <stdio. h> # include <iostream> # include <map> # include <set> # include <bitset> # include <list> # include <stack> # include <vector> # include <math. h> # include <string. h> # include <queue> # include <string> # include <stdlib. h >#include <algorithm> # define ll _ int64 // # define ll long # define EPS 1e-9 # define PI ACOs (-1.0) using namespace STD; const ll INF = 1 <30; const int maxn = 100010; int test; ll N; int A [maxn], num [maxn]; int prime [maxn]; bool flag [maxn]; int fact [maxn] [20]; int coun [maxn]; void getprime () {memset (flag, 0, sizeof (FLAG )); flag [1] = true; prime [0] = 0; For (INT I = 2; I <maxn; I ++) {If (flag [I] = false) prime [++ prime [0] = I; for (Int J = 1; j <= prime [0] & I * prime [J] <maxn; j ++) {flag [prime [J] * I] = true; if (I % prime [J] = 0) Break ;}} void getfact (INT dig, int POS) {int TMP = dig; For (INT I = 1; I <= prime [0] & prime [I] * prime [I] <= TMP; I ++) {If (TMP % prime [I] = 0) {fact [POS] [coun [POS] ++] = prime [I]; while (TMP % prime [I] = 0) tmp/= prime [I];} If (TMP = 1) break;} If (TMP> 1) fact [POS] [coun [POS] ++] = TMP;} void Init () {for (INT I = 2; I <= 100000; I ++) {for (Int J = I + I; j <= 100000; j + = I) num [I] + = num [J] ;}} int main () {getprime (); scanf ("% d", & Test); While (test --) {memset (Num, 0, sizeof (Num )); scanf ("% i64d", & N); For (INT I = 1; I <= N; I ++) {scanf ("% d ", & A [I]); num [A [I] ++;} Init (); memset (coun, 0, sizeof (coun); LL ans = 0; for (INT I = 1; I <= N; I ++) {ll res = 0; getfact (A [I], I); For (Int J = 1; j <(1 <coun [I]); j ++) {ll ansnum = 1; int CNT = 0; For (int K = 0; k <coun [I]; k ++) {If (J & (1 <k) {ansnum * = fact [I] [k]; CNT ++ ;}}if (CNT & 1) RES + = (Num [ansnum]-1); elseres-= (Num [ansnum]-1 );} ans + = (n-1-res) * res;} ans = N * (n-1) * (n-2)/6-ans/2; // note that N is llprintf ("% i64d \ n", ANS);} return 0 ;}
HDU 5072 Coprime (same-color triangle + rejection)