Pagini recente » Cod sursa (job #2715786) | Cod sursa (job #38094) | Cod sursa (job #2944382) | Cod sursa (job #2953442) | Cod sursa (job #2835292)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int gcd(int a, int b) {
if (b == 0) {
return a;
} else {
return gcd(b, a % b);
}
}
long long v1(int n) {
long long fractionsCount = 0;
for (int a = 1; a <= n; ++a) {
int count = 0;
for (int b = 1; b <= n; ++b) {
if (gcd(a, b) == 1) {
fractionsCount++;
count++;
}
}
if (a > 1 && n == 36) {
// printf("%d ", count);
}
}
if (n == 36) {
// printf("\n");
}
return fractionsCount;
}
long long v2(int n) {
if (n == 1) {
return 1;
}
long long fractionsCount = n;
int primeDivisors[8];
int primeDivisorsCount = 0;
int *array = calloc(n, sizeof(int));
for (int num = 2; num <= n; ++num) {
primeDivisorsCount = 0;
int clone = num;
if (clone % 2 == 0) {
primeDivisors[primeDivisorsCount++] = 2;
do {
clone >>= 1;
} while (clone % 2 == 0);
}
for (int div = 3; div <= clone; div += 2) {
if (clone % div == 0) {
primeDivisors[primeDivisorsCount++] = div;
do {
clone /= div;
} while (clone % div == 0);
}
}
switch (primeDivisorsCount) {
case 0:
fractionsCount += n - n / num;
break;
case 1:
fractionsCount += n - n / primeDivisors[0];
break;
case 2:
fractionsCount +=
n - (n / primeDivisors[0] + n / primeDivisors[1] - n / (primeDivisors[0] * primeDivisors[1]));
break;
default: {
memset(array, 0, n * sizeof(int));
for (int index = 0; index < primeDivisorsCount; ++index) {
for (int i = primeDivisors[index]; i <= n; i += primeDivisors[index]) {
array[i - 1] = 1;
}
}
for (int index = 0; index < n; ++index) {
if (array[index] == 0) {
fractionsCount++;
}
}
}
break;
}
}
free(array);
return fractionsCount;
}
int *getPrimeNumbersUntil(int n) {
int *array = (int *) calloc(n + 1, sizeof(int));
for (int i = 2; i <= n; ++i) {
if (array[i] == 0) {
for (int j = 2 * i; j <= n; j += i) {
array[j] = 1;
}
}
}
return array;
}
int computeCombinationSum(int *divisors, int divisorsCount) {
int sum = -1;
int value = divisorsCount - 2;
for (int i = 1; i <= value; ++i) {
switch (i) {
case 1:
for (int index = 0; index < divisorsCount; ++index) {
sum += divisors[index];
}
break;
default:
sum = -1;
}
}
return sum;
}
long long v3(int n) {
if (n == 1) {
return 1;
}
int *primeNumbers = getPrimeNumbersUntil(n);
long long fractionsCount = n;
// long long oldFraction = fractionsCount;
int primeDivisors[8];
int divisorStats[15] = {0};
int primeDivisorsCount = 0;
int *array = calloc(n, sizeof(int));
for (int num = 2; num <= n; ++num) {
primeDivisorsCount = 0;
if (primeNumbers[num] == 1) {
int clone = num;
for (int div = 2; div <= clone; ++div) {
if (primeNumbers[clone] == 0) {
primeDivisors[primeDivisorsCount++] = clone;
break;
}
if (primeNumbers[div] == 0) {
if (clone % div == 0) {
primeDivisors[primeDivisorsCount++] = div;
do {
clone /= div;
} while (clone % div == 0);
}
}
}
}
int divisorsProduct = 1;
for (int i = 0; i < primeDivisorsCount; ++i) {
divisorsProduct *= primeDivisors[i];
}
divisorStats[primeDivisorsCount]++;
switch (primeDivisorsCount) {
case 0:
fractionsCount += n - n / num;
break;
case 1:
fractionsCount += n - n / primeDivisors[0];
break;
case 2:
fractionsCount +=
n - (n / primeDivisors[0] + n / primeDivisors[1] - n / (primeDivisors[0] * primeDivisors[1]));
break;
case 3:
fractionsCount +=
n - (
n / primeDivisors[0] +
n / primeDivisors[1] +
n / primeDivisors[2] -
(
n / (primeDivisors[0] * primeDivisors[1]) +
n / (primeDivisors[0] * primeDivisors[2]) +
n / (primeDivisors[1] * primeDivisors[2]) -
n / (primeDivisors[0] * primeDivisors[1] * primeDivisors[2])
)
);
break;
default: {
memset(array, 0, n * sizeof(int));
for (int index = 0; index < primeDivisorsCount; ++index) {
for (int i = primeDivisors[index]; i <= n; i += primeDivisors[index]) {
array[i - 1] = 1;
}
}
for (int index = 0; index < n; ++index) {
if (array[index] == 0) {
fractionsCount++;
}
}
}
break;
}
if (n == 36) {
// printf("%d ", fractionsCount - oldFraction);
}
// oldFraction = fractionsCount;
}
if (n == 36) {
// printf("\n");
}
// for (int i = 0; i < 15; ++i) {
// printf("%d : %d\n", i, divisorStats[i]);
// }
free(array);
free(primeNumbers);
return fractionsCount;
}
long long v4(int n) {
if (n == 1) {
return 1;
}
int *primeNumbers = getPrimeNumbersUntil(n);
long long fractionsCount = 1;
int primeDivisors[8];
int primeDivisorsCount = 0;
for (int num = 2; num <= n; ++num) {
primeDivisorsCount = 0;
if (primeNumbers[num] == 1) {
int clone = num;
for (int div = 2; div <= clone; ++div) {
if (primeNumbers[clone] == 0) {
primeDivisors[primeDivisorsCount++] = clone;
break;
}
if (primeNumbers[div] == 0) {
if (clone % div == 0) {
primeDivisors[primeDivisorsCount++] = div;
do {
clone /= div;
} while (clone % div == 0);
}
}
}
} else {
primeDivisors[primeDivisorsCount++] = num;
}
int product = 1;
int divProduct = 1;
for (int i = 0; i < primeDivisorsCount; ++i) {
product *= primeDivisors[i] - 1;
divProduct *= primeDivisors[i];
}
fractionsCount += 2 * num / divProduct * product;
}
free(primeNumbers);
return fractionsCount;
}
int main() {
char *inFileName = "fractii.in";
char *outFileName = "fractii.out";
FILE *in = fopen(inFileName, "r");
if (in == NULL) {
printf("Cannot open %s.\n", inFileName);
return 1;
}
FILE *out = fopen(outFileName, "w");
int n;
fscanf(in, "%d", &n);
if (n == 1) {
fprintf(out, "1");
} else {
fprintf(out, "%lld\n", v4(n));
}
fclose(in);
fclose(out);
return 0;
}