Cod sursa(job #122807)

Utilizator marinMari n marin Data 13 ianuarie 2008 18:26:27
Problema Fractii Scor 10
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.24 kb
#include <stdio.h>
#define DIM 1000001
char v[DIM];
long int p[DIM];
long long tot[DIM];

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

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

  for (i=2;i<=n;i++) {
    if (i==2) pas=2;
    else pas=i+i;
    if (v[i]==0)
      for (j=i+pas;j<=n;j+=pas)
        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)

  
  long int prim, ultim, mij;
  prim=1;
  ultim=k;
  while (prim<=ultim){
    mij = (prim+ultim)/2;
    if (p[mij]==n){
      prim=mij;
      break;
    }
    else
      if (p[mij]>n)
        ultim=mij-1;
      else prim=mij+1;

  }
  
  

  tot[1]=1;
  tot[2]=1;

  cnt=2;



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

	sum+=(tot[i]+tot[i]);
      }
//    if (cnt==n)
//      break;
  }
/*  sum=1;
  for (i=2;i<=n;i++)
    sum+=(2*tot[i]);*/
  if (n==1)
     sum=1;
  else if (n==2) sum=3;
  else sum+=3;




/*  tot[1]=1;
  tot[2]=1;
  for (i=3;i<=n;i++){
    if (tot[i]!=0) 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;
}