Cod sursa(job #1699559)

Utilizator oldatlantianSerban Cercelescu oldatlantian Data 7 mai 2016 19:50:45
Problema Pairs Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.29 kb
#include <bits/stdc++.h>
using namespace std;
typedef long long i64;

bool c[1000005];
int  v[100005], prs[1000005], aux[1000005];

inline void erat(int n) {
    c[0] = 1;
    c[1] = 1;
    for(int i=4; i<=n; i+=2)
        c[i] = 1;
    for(int i=3; i<=n; i+=2){
        if(c[i]) continue;
        for(i64 j=1LL*i*i; j<=n; j+=i+i)
            c[j] = 1;
    }
    for(int t=0, i=2; i<=n; ++i)
        if(!c[i])
            prs[t++] = i;
}

inline int cbits(int arg) {
    int ans = 0;
    while(arg) {
        if(arg&1)
            ++ans;
        arg>>=1;
    }
    return ans;
}

inline void pinex(int arg) {
    int pd[10];
    int prod, top;

    top = 0;

    for(int i=0; prs[i]*prs[i]<=arg; ++i){
        if(arg%prs[i]==0) {
            pd[top++]=prs[i];
            while(arg%prs[i]==0)
                arg /= prs[i];
        }
    }
    if(arg>1)
        pd[top++] = arg;

    for(int lim=(1<<top), i=1; i<lim; ++i) {
        prod = 1;
        for(int j=0; (1<<j)<=i; ++j)
            if(i&(1<<j))
                prod*=pd[j];
        ++aux[prod];
    }
}

inline int brothers(int arg) {
    int pd[10];
    int prod, ans, top;

    top = 0;
    ans = 0;

    for(int i=0; prs[i]*prs[i]<=arg; ++i){
        if(arg%prs[i]==0) {
            pd[top++]=prs[i];
            while(arg%prs[i]==0)
                arg /= prs[i];
        }
    }
    if(arg>1)
        pd[top++] = arg;

    for(int lim=(1<<top), i=1; i<lim; ++i) {
        prod = 1;
        for(int j=0; (1<<j)<=i; ++j)
            if(i&(1<<j))
                prod*=pd[j];
        if(cbits(i)&1)
            ans+=aux[prod];
        else
            ans-=aux[prod];
    }
//    if(top&1)
//        --ans;
//    else
//        ++ans;
    return ans-1;
}

int main(void) {
    FILE *fi = fopen("pairs.in","r");
    FILE *fo = fopen("pairs.out","w");
    int n, mx;
    i64 b, ans;

    mx =-1;
    b  = 0LL;

    fscanf(fi,"%d",&n);
    for(int i=0; i<n; ++i) {
        fscanf(fi,"%d",&v[i]);
        mx = max(mx, v[i]);
    }
    erat(mx);

    for(int i=0; i<n; ++i)
        pinex(v[i]);

    for(int i=0; i<n; ++i)
        b  += brothers(v[i]);
    b/=2;

    ans = 1LL*n*(n-1)/2-b;

    fprintf(fo,"%lld",ans);

    fclose(fi);
    fclose(fo);
    return 0;
}