Cod sursa(job #118047)

Utilizator floringh06Florin Ghesu floringh06 Data 23 decembrie 2007 00:10:25
Problema Pairs Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.37 kb
// 100 puncte
#include <cstdio>
#include <cstring>
#include <cmath>

using namespace std;

#define FIN "pairs.in"
#define FOUT "pairs.out"
#define MAX_N 100005
#define MAX_M 1000002

int A[MAX_N];
long long x[MAX_M];

unsigned char P[MAX_M];
unsigned char E[MAX_M];
int Prim[80000];

int N, i, max;
int Np;

long long Res;

    void preproc ( void )
    {
         int i, j, p;
         for (i = 1; i <= N; ++i) P[A[i]] = 1;
         for (i = 2; i <= max; ++i)
         {
              p = max/i;
              for (j = 1; j <= p; ++j) if (P[j*i] == 1) ++x[i];
         }
    }
    
    void generate ( void )
    {
         int i, j;
         int Lim = int (sqrt(max)) + 5;
         
         for (i = 2; i <= Lim; ++i)
         {
             j = i*i;
             while (j <= max)
             {
                   E[j] = 1; j += i;
             }
         }
         j = 0;
         for (i = 2; i <= max; ++i)
             if (E[i] != 1) Prim[++j] = i;
         Np = j;
    }

    void solve ( void )
    {
         int i, j, br;
         for (i = 2; i <= max; ++i)
         {
             int p = i, h = 0;
             // initializari
             j = 1; br = 0;
             
             if (x[i] <= 1) continue;
             while (Prim[j] <= int(sqrt(p)) + 2 && p > 1)
                   if (!(p % Prim[j]))
                   {
                      // actualizez starea     
                      ++h; p/=Prim[j];
                      if (!(p %Prim[j]))
                      {
                         br = 1; h = 0;
                         break;
                      }
                   }
                   else ++j;
             if (p > 1 && !br) ++h;
             if (h > 0)
                if (h&1) Res += (long long)x[i]*(x[i] - 1)/2;
                   else  Res -= (long long)x[i]*(x[i] - 1)/2;
         }       
         long long Sol = N;
         Sol = (Sol*(Sol - 1)) >> 1;
         Sol -= Res;
         printf ("%lld\n", Sol);
    } 

    int main ()
    {
        freopen (FIN, "r", stdin);
        freopen (FOUT, "w", stdout);
        
        scanf ("%d", &N);
        for (i = 1; i <= N; ++i)
        {
            scanf ("%d", A + i);
            if (A[i] > max) max = A[i];
        }
        
        preproc ();
        generate ();
        solve ();
        
        return 0;
    }