Cod sursa(job #87274)

Utilizator MarcvsHdrMihai Leonte MarcvsHdr Data 26 septembrie 2007 21:48:34
Problema Sum Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.2 kb
# include <stdio.h>
# include <math.h>

const long int MAXN=100000;

long int task[MAXN+1],n,ciurlen;
long long int memo[MAXN+1];

const long int ciur[120]={0,2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349};

void citire()
{
FILE *f=fopen("sum.in","r");
fscanf(f,"%ld",&n);
long int i;
for (i=1;i<=n;i++)
	fscanf(f,"%ld",&task[i]);
fclose(f);
}

void det_primes()
{
long int prim,i,j;
float bound;
ciur[1]=2;ciurlen=1;
for (i=2;i<=350;i++)
	{
	prim=1;
	bound=sqrt(i)+1;
	for (j=1;j<=ciurlen&&prim&&ciur[j]<=bound;j++)
		if (i%ciur[j]==0) prim=0;
	if (prim) ciur[++ciurlen]=i;
	}
}

long long int sigma(long int a) {return (long long int)a*(a+1)/2;}
long long int sign(long int a) {if (a%2==1) return -1; return 1;}

void calculeaza()
{
long int qwd,aux,iaux,nrc,i,siaux,coef,facts[10],factslen=0;
long long int solloc;
FILE *g=fopen("sum.out","w");
for (qwd=1;qwd<=n;qwd++)
	{
	aux=task[qwd];
	if (memo[aux]==0)
	{
	iaux=1;
	factslen=0;
	while (aux!=1&&iaux<=ciurlen)
		{
		if (ciur[iaux]>sqrt(aux)+1) break;
		if (aux%ciur[iaux]==0)
			{
			facts[++factslen]=ciur[iaux];
			while (aux%ciur[iaux]==0) aux/=ciur[iaux];
			}
		iaux++;
		}
	if (aux!=1) facts[++factslen]=aux;
	//avem in factslen descompunerea in factori. acuma sa facem
	//includerea si excluderea
	solloc=0;
	for (iaux=1;iaux<=(1<<factslen)-1;iaux++)
		{
		siaux=iaux;
		//sa determinam coeficientii
		for (nrc=0,i=1,coef=1;i<=factslen;i++,siaux/=2)
			if (siaux%2==1)
				{
				coef*=facts[i];
				nrc++;
				}
		solloc+=sign(nrc)*coef*sigma(2*task[qwd]/coef);
		}
	solloc+=sigma(2*task[qwd]);
	memo[task[qwd]]=solloc;
	}
	fprintf(g,"%lld\n",memo[task[qwd]]);
	}
fcloseall();
}

void scrie_primes()
{
FILE *f=fopen("auxil.out","w");
long int i;
for (i=1;i<=ciurlen;i++)
	{
	fprintf(f,"%ld,",ciur[i]);
	if (i==100) fprintf(f,"\n");
	}
fcloseall();
}

int main()
{
citire();
//determinam toate numerele prime pana la 50000
//det_primes();
//scrie_primes();
calculeaza();
return 0;
}