Cod sursa(job #129125)

Utilizator tErMyAndrei Panturu tErMy Data 28 ianuarie 2008 17:59:41
Problema Pairs Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.66 kb
 #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;  
     }