ACM has been retired for two years. I did not expect this year's chance to join regional in Anshan. I remember that I was very excited when I joined regional for the first time and it was hard to describe it. This time, the pressure on regional was everywhere, and it felt easier than taking part in the provincial competition, even like doing exercises. Because the level was not high, and after two years, I took a bronze medal without any suspense.
At the time of the competition, question C had basically come up with an understanding method. Due to the time, it failed to pass.
Question C is now in question 5072 of HDU.
Question: N numbers (n <100000) are given. Each number cannot exceed 100000, and no number is repeated. Now, I will randomly select three and ask how many of them are mutually qualitative or the three are not mutually qualitative.
Idea: the prototype of this question is a triangle of the same color. Many teams on the scene may know this model, so there were quite a lot of teams who used this question at the time.
In contrast, there is only one pair of or only two pairs of data.
After the study, we found that for each number to find the number K is not the same as the number k so sum (K * (n-1-k)/2 is the opposite number, so the final answer is C (n, 3) -sum (K * (n-1-k)/2.
There is still a problem: how to find the number of non-reciprocal numbers of each number, which is actually based on the principle of rejection. For number A, obtain all prime factors of A, and then enumerate all the numbers that prime factors can constitute (the prime factor cannot exceed 1 in the process of making up a number) W,
Obtain the number of W in the original array. If the number of prime factors of W is an odd number, it is added and the even number is reduced. This is the process of rejection.
There is still a problem, how to quickly calculate the number of W in the original array. First, calculate all prime factors for each digit A in the original data, and then enumerate all the numbers that prime factors can constitute (the number of prime factors cannot exceed 1 in the process of making up the number ),
Add 1 to the number statistics of each enumeration so that preprocessing can be performed in advance.
The overall complexity of the algorithm is O (n * 64*6 );
AC code:
#include <cstdio>#include <cstring>#include <queue>#include <string>#include <iostream>using namespace std;const int N = 200500;typedef long long LL;int p[N];int num;bool in[N];int a[N];int n;int nn[N];void get_prime(){ num = 0; for(int i=2; i<N; i++) { if(!in[i]) { p[num++] = i; for(int j=i; j<N; j+=i) { in[j] = true; } } }}void init(){ memset(nn, 0, sizeof(nn)); int cnt = 0; int ele[100]; scanf("%d", &n); int temp = 0; for(int i=0; i<n; i++) { scanf("%d", &a[i]); temp = a[i]; cnt = 0; for(int j=0; p[j]*p[j] <= temp; j++) { if(temp % p[j] == 0) { ele[cnt++] = p[j]; while(temp%p[j] == 0) temp /= p[j]; } } if(temp != 1) { ele[cnt++] = temp; } for(int j=1; j<(1<<cnt); j++) { temp = 1; for(int k=0; k<cnt; k++) { if( (1<<k) & j ) { temp *= ele[k]; } } nn[temp]++; } }}void solve(){ LL ans = n; LL ss = 0; int temp; ans = ans*(n-1)*(n-2)/6; for(int i=0; i<n; i++) { int cnt = 0; int ele[100]; temp = a[i]; cnt = 0; for(int j=0; p[j]*p[j] <= temp; j++) { if(temp % p[j] == 0) { ele[cnt++] = p[j]; while(temp%p[j] == 0) temp /= p[j]; } } if(temp != 1) { ele[cnt++] = temp; } LL ret = 0; for(int j=1; j<(1<<cnt); j++) { temp = 1; int hh = 0; for(int k=0; k<cnt; k++) { if( (1<<k) & j ) { temp *= ele[k]; hh++; } } if(hh%2 == 1) ret += nn[temp]; else ret -= nn[temp]; } if(ret == 0) continue; ss = ss + (ret-1)*(n-ret); // cout<<i<<" "<<ret<<" "<<ss<<endl; } cout<<ans - ss/2<<endl;}int main(){ get_prime(); int t; scanf("%d", &t); while(t--) { init(); solve(); } return 0;}View code
2014 ACM regional HDU 5072