Pagini recente » Istoria paginii runda/a_b/clasament | Cod sursa (job #1653991) | Cod sursa (job #1572180) | Cod sursa (job #771629) | Cod sursa (job #1718783)
#include <fstream>
#include <iostream>
using namespace std;
ifstream f("fractii.in");
ofstream g("fractii.out");
void addF(short tata[],int nr,int prim)
{
if( tata[nr] == 0) tata[nr] = prim;
}
int main()
{
int n,k,i;
long long s;
bool v[1000001];
short tata[1000001] = {0};
int sume[1000001] = {0};
f>>n;
for(i = 1;i <= n;i++) v[i] = true; /* initializare */
k = 2;
while(k<=n)
{
sume[k] = k-1; /* k-1 fractii ireductibile de tipul i / k, unde i < k */
v[k] = false;
for(i=2*k;i<=n;i += k)
{
v[i] = false;
addF(tata,i,k); //adauga numai daca nu are deja
}
while(v[k] == false && k<=n)
{
k++;
}
}
for(i=2;i<=n;i++)
if(sume[i] == 0) // numarul nu este prim, deci are "tata"
{
short aux;
int pow = 0,
a = i;
do{
pow++; //numara ordinul puterii
aux = tata[a]; // cel mai mic divizor in afara de 1
a = a/aux; // impartim pe a la acel divizor
}while(aux == tata[a]);
if(pow > 1 || aux*aux == i)
sume[i] = aux*sume[i/aux]; /* formula */
else
sume[i] = sume[aux]*sume[i/aux];
}
s=1; /* prima fractie 1/1 */
for(i=2;i<=n;i++) s += 2*sume[i];
g<<s;
f.close();
g.close();
return 0;
}