Cod sursa(job #122406)

Utilizator marinMari n marin Data 12 ianuarie 2008 11:12:28
Problema Fractii Scor 50
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.33 kb
#include <stdio.h>
#define DIM 100001
char v[DIM];
long int p[DIM];
long long tot[DIM];

long long sum;
long int e,d,k,n,j,i,a;

int main(){
  FILE *f = fopen("fractii.in","r");
  fscanf(f,"%lld",&n);
//  scanf("%d",&n);
  fclose(f);
  for (i=1;i<=n;i++)
    v[i]=0;
  for (i=2;i<=n;i++)
    for (j=2*i;j<=n;j+=i)
      v[j]=1;

  k=0;
  for (i=2;i<=n;i++)
    if (v[i]==0)
      p[++k]=i;
//      printf("%d ",i);
//  printf("\n");


//t(p^e) = (p - 1) * p^(e - 1), p numar prim (din definitie)
//si
//daca p numar prim, p NU divide a,
//t(p^e * a) = t(p^e) * t(a) = (p - 1) * p^(e - 1) * t(a)


  tot[1]=1;
  tot[2]=1;
  for (i=3;i<=n;i++){
/*    if (v[i]==0){
      tot[i]=2*(i-1);
      continue;
    }*/
    for (j=1;(p[j]<=i)&&(j<=k);j++){
      d = p[j];
      if (i%d==0){
	e=0;  a=i;
	while (a%d==0) {
	  e++;
	  a/=d;
	}
	if (a==1) {
	  tot[i]=((long long)(d-1))*(i/d);
	} else {
	  tot[i]=tot[a]*tot[i/a];
	}
	break;
      }

    }
  }
  sum=1;
  for (i=2;i<=n;i++)
    sum+=(2*tot[i]);

/*  sum=0;
  for (x=1;x<=n;x++){
    pp=1;
    nn=x;
    for (i=1;(p[i]<=x)&&(i<=k);i++)
      if (x%p[i]==0) {
	nn/=p[i];
	pp*=(p[i]-1);
      }
    pp*=nn;
    sum+=pp;
  }
  sum=sum*2-1;*/
  FILE *g = fopen("fractii.out","w");
  fprintf(g,"%lld",sum);
  fclose(g);
  return 0;
}