Cod sursa(job #188976)

Utilizator anna_bozianuBozianu Ana anna_bozianu Data 11 mai 2008 11:28:53
Problema Fractii Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.56 kb
#include<stdio.h>      
unsigned long long phi[1000001],i,j,k,sol,n;   
int main()   
{      
    freopen("fractii.in","rt",stdin);   
    freopen("fractii.out","wt",stdout);   
    scanf("%llu",&n);   
    phi[1]=1;sol=1;   
    for(i=2;i<=n;i++)   
    { if(!phi[i])   
      { phi[i]=i-1;   
        for(j=i*i;j<=n;j+=i)   
           phi[j]=i;   
           
      }   
      else  
      { j=phi[i]; phi[i]=j-1; k=i/j;   
        while(k%j==0){phi[i]*=j;k/=j;}   
        phi[i]*=phi[k];   
      }   
      sol+=2*phi[i];   
     }   
     printf("%llu",sol);   
     return 0;   
}   
// phi[i]=indicatorul lui euler al numarului i   
// phi[i]=numarul de numere mai mici decat i si prime cu i   
// phi[i]=numarul de fractii ireductibile j/i cu j<i   
//       =numarul de fractii ireductibile i/j cu j<i   
// sol=1+suma(2*phi[i])   
// folosim phi[p]=p-1;pentru p=numar prim   
// phi[p^k]=(p-1)*p^(k-1);pentru p=numar prim   
// phi[m1*m2]=phi[m1]*phi[m2] daca m1,m2 prime intre ele   
// se obtine urmatorul algoritm care utilizeaza ciurul lui eratostene   
// formulele de mai sus si programare dinamica   
// daca pt i de la 1 la n in phi[i] avem 0 atunci i este prim si facem   
// phi[i]=i-1   
// marcam apoi multiplii lui i pt care i este factorul prim minimal prin   
// marcajul phi[i]=i   
// daca in phi[i] avem p!=0 atunci p este cel mai mic factor prim pt i   
// atunci putem scrie i=m1*m2 unde m=p^k si m2 nu contine p deci e prim cu m1   
// aplicam acum formula pt phi[m1]=phi[p^k]   
// si luam din spate valoarea lui phi[m2]