Pagini recente » Cod sursa (job #2700520) | Cod sursa (job #1885965) | Cod sursa (job #130944) | Cod sursa (job #1276850) | Cod sursa (job #1562034)
#include <stdio.h>
#define MAX_VAL 1000000
#define MAX_P 78500
#define LIMIT 1000
#define Nadejde 8
#define ll long long
int N;
int low[MAX_VAL + 1]; // low[i] = cel mai mic numar prim care il divide pe i.
int freq[MAX_VAL + 1]; // freq[i] = de cate ori apare "i" ca divizor.
int size, div[Nadejde];
/** Ciurul lui Eratostene. **/
void sieve() {
int i, j, step;
low[2] = 2;
for (i = 3; i < LIMIT; i += 2) {
if (!low[i]) {
low[i] = i;
for (step = (i << 1), j = i * i; j <= MAX_VAL; j += step) {
if (!low[j]) {
low[j] = i;
}
}
}
}
for (; i < MAX_VAL; i += 2) {
if (!low[i]) {
low[i] = i;
}
}
}
/** Obtine divizorii lui "x". **/
void getDiv(int x) {
int curr;
size = 0;
if (x % 2 == 0) {
div[size++] = 2;
x /= (x & -x);
}
while (x > 1) {
div[size++] = (curr = low[x]);
do {
x /= curr;
} while (curr == low[x]);
}
}
/** Principiul includerii si al excluderii. **/
void bkt(int level, ll int x, int card) {
if (level == size) {
return;
}
/* Nu bagam in seama divizorul curent. */
bkt(level + 1, x, card);
/* Il bagam in seama. */
card++;
x = x * div[level];
if (card & 1) {
freq[x]++;
} else {
freq[x]--;
}
bkt(level + 1, x, card);
}
int main(void) {
int i, val;
FILE *f = fopen("pairs.in", "r");
sieve();
/* Citirea datelor. */
fscanf(f, "%d", &N);
for (i = 0; i < N; i++) {
fscanf(f, "%d", &val);
getDiv(val);
bkt(0, 1, 0);
}
fclose(f);
/* Calcularea solutiei. */
ll int count = 0;
for (i = 2; i <= MAX_VAL; i++) {
if (freq[i] > 0) {
count += ((ll)freq[i] * (freq[i] - 1)) / 2;
} else if (freq[i] < 0) {
count -= ((ll)-freq[i] * (-freq[i] - 1)) / 2;
}
}
count = (((ll)N * (N - 1)) / 2) - count;
/* Afisarea solutiei. */
freopen("pairs.out", "w", stdout);
fprintf(stdout, "%lld\n", count);
fclose(stdout);
/// Multumim Doamne!
puts("Doamne ajuta!");
return 0;
}