Cod sursa(job #109499)

Utilizator vlad_popaVlad Popa vlad_popa Data 25 noiembrie 2007 11:28:46
Problema Pairs Scor 60
Compilator cpp Status done
Runda preONI 2008, Runda 1, Clasa a 10-a Marime 2.51 kb
using namespace std;

#include <cstdio>

#define FIN "pairs.in"
#define FOUT "pairs.out"
#define NMAX 1<<17

int V[NMAX], N, Ct[1000001], NP[8], Nr, P[80000], Np;
char E[1000001];

void read ()
{
    scanf ("%d\n", &N);
    
    int i, j, tmp, pow, k;
    
    for (i = 2; i <= 1000; ++ i)
        if (E[i] != 1)
        {
            P[++ Np] = i;
            for (j = i + i; j <= 1000000; j += i)
                E[j] = 1;
        }
    for (i = 1001; i <= 1000000; ++ i)
        if (E[i] != 1)
            P[++ Np] = i;
    //printf ("%d\n", Np);
    
    for (i = 1; i <= N; ++ i)   
    {
        scanf ("%d\n", V + i);
        tmp = V[i];
        Nr = 0;
        
        for (j = 1; E[tmp] != 0; ++ j)
            if (!(tmp % P[j]))
            {
                NP[++ Nr] = P[j];
                while (!(tmp % P[j]))
                    tmp /= P[j];
            }
        if (tmp != 1)
            NP[++ Nr] = tmp;
            
        /*for (j = 1; j <= Nr; ++ j)
            printf ("%d ", NP[j]);
        printf ("\n");*/
            
        pow = (1 << Nr);
        for (j = 1; j < pow; ++ j)
        {
            tmp = 1;        
            for (k = 0; k < Nr; ++ k)
                if (j & (1 << k))
                    tmp *= (NP[k + 1]);
            ++ Ct[tmp];
        }
    }
    
    /*for (i = 1; i <= 20; ++ i)
        printf ("%d ", Ct[i]);*/
}

void solve ()
{
    int i, tmp, j, k, sol, Ans = 0, pow, cnt;
    
    for (i = 1; i <= N; ++ i)
    {
        sol = Nr = 0;
        tmp = V[i];
        
        for (j = 1; E[tmp] != 0; ++ j)
            if (!(tmp % P[j]))
            {
                NP[++ Nr] = P[j];
                while (!(tmp % P[j]))
                    tmp /= P[j];
            }
        if (tmp != 1)
            NP[++ Nr] = tmp;       
        pow = (1 << Nr);
            
        for (j = 1; j < pow; ++ j)
        {
            tmp = 1;
            cnt = 0;
            for (k = 0; k < Nr; ++ k)
                if (j & (1 << k))
                {
                    tmp *= (NP[k + 1]);
                    ++ cnt;
                }
            if (cnt & 1)
                sol += Ct[tmp];
            else
                sol -= Ct[tmp];
        }
        
        //printf ("%d\n", sol);
        Ans += N - sol;
    }
    
    printf ("%d\n", Ans / 2);
}

int 
 main ()
{
    freopen (FIN, "rt", stdin);
    freopen (FOUT, "wt", stdout);
    
    read ();
    solve ();
    
    return 0;
}