HDU 5072 Coprime

来源:互联网 发布:swift for windows 编辑:程序博客网 时间:2024/05/21 09:59
容斥原理,从反面想,就是红蓝三角形的计数。
#include <cstdio>#include <cstring>#include <vector>using namespace std;const int MAXN = 100005;int a[MAXN], n;const long N = 100005;long prime[N] = {0},num_prime = 0;int isNotPrime[N] = {1, 1};void produce_prime(){    for(long i = 2 ; i < N ; i ++)    {        if(! isNotPrime[i])            prime[num_prime ++]=i;        for(long j = 0 ; j < num_prime && i * prime[j] <  N ; j ++)        {                        isNotPrime[i * prime[j]] = 1;            if( !(i % prime[j] ) )                break;        }    }}vector<int> g[MAXN];int fac[MAXN];//fac[i]表示a[]中是i的倍数的个数int main(){    produce_prime();    for (int i = 0; i < num_prime; i ++) {        for (int j = 1; prime[i] * j < MAXN; j ++) {            g[prime[i] * j].push_back((int)prime[i]);        }    }    int T;    scanf("%d", &T);    while (T --) {        memset(fac, 0, sizeof(fac));        scanf("%d", &n);        for (int i = 0; i < n; ++ i) {            scanf("%d", &a[i]);            int size = (int)g[a[i]].size();            for (int j = 0; j < (1 << size); j ++) {                int base = 1;                for (int k = 0; k < size; k ++) {                    if ((j >> k) & 1) {                        base *= g[a[i]][k];                    }                }                fac[base] ++;            }        }        long long res = 0;        for (int i = 0; i < n; i ++) {            if (a[i] == 1) {                continue;            }            long long tem_val = 0;            int size = (int)g[a[i]].size();            for (int j = 0; j < (1 << size); j ++) {                int cnt = 0, base = 1;                for (int k = 0; k < size; k ++) {                    if ((j >> k) & 1) {                        cnt ++;                        base *= g[a[i]][k];                    }                }                if (cnt & 1) {                    tem_val -= (fac[base] - 1);                }                else                {                    tem_val += (fac[base] - 1);                }            }            tem_val = 1ll * tem_val * (n - 1 - tem_val);            res += tem_val;        }        res /= 2;        res = 1ll * n * (n - 1) * (n - 2) / 6 - res;        printf("%lld\n", res);    }    return 0;}


0 0
原创粉丝点击