Pagini recente » Cod sursa (job #2696589) | Cod sursa (job #2669074) | Cod sursa (job #352725) | Cod sursa (job #1404192) | Cod sursa (job #841142)
Cod sursa(job #841142)
#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <vector>
#include <bitset>
using namespace std;
#define NMAX 100010
long long rez = 0;
int N, stepmax;
int pr[300];
int a[NMAX];
int b[NMAX];
int c[NMAX];
int d[NMAX];
char am[NMAX];
char bm[NMAX];
char cm[NMAX];
bitset <300000> ap;
int kkt[300000];
int prim(int x)
{
int i;
for (i = 2; i * i <= x; i++)
if (x % i == 0) return 0;
return 1;
}
inline int srch(int q)
{
int step = stepmax, x = 0;
for (; step; step >>= 1)
if (x + step <= N && d[x + step] <= q)
x += step;
return x;
}
long long numar(int x)
{
// numar cate perechi dau toate alea divizibile la x
int i;
long long rez = 0;
ap = 0;
for (i = 1; i <= N; i++) {
// if (x > a[i]) am[i] = a[i]; else am[i] = a[i] % x;
// if (x > b[i]) bm[i] = b[i]; else bm[i] = b[i] % x;
// if (x > c[i]) cm[i] = c[i]; else cm[i] = c[i] % x;
am[i] = a[i]; while (am[i] >= x) am[i] -= x;
bm[i] = b[i]; while (bm[i] >= x) bm[i] -= x;
cm[i] = c[i]; while (cm[i] >= x) cm[i] -= x;
d[i] = (am[i] * 4225) + (bm[i] * 65) + cm[i] % x;
if ((2 * a[i]) % x == 0 && (2 * b[i] % x == 0) && (2 * c[i] % x == 0)) rez--;
// if ( (am[i] + am[i] == x || am[i] + am[i] == 2 * x) && (bm[i] + bm[i] == x || bm[i] + bm[i] == 2 * x) && (cm[i] + cm[i] == x || cm[i] + cm[i] == 2 * x)) rez--;
if (!ap[d[i]]) kkt[d[i]] = 0;
kkt[d[i]]++;
ap[d[i]] = 1;
}
// sort(d + 1, d + N + 1);
int aa, bb, cc, nnr;
for (i = 1; i <= N; i++) {
aa = x - am[i]; if (aa == x) aa = 0;
bb = x - bm[i]; if (bb == x) bb = 0;
cc = x - cm[i]; if (cc == x) cc = 0;
if (aa > 64 || bb > 64 || cc > 64) continue;
nnr = (aa * 4225) + (bb * 65) + cc;
if (!ap[nnr]) continue;
rez += kkt[nnr];
}
return (rez >> 1);
}
void back(int k, int last, int nr)
{
if (nr != 1) {
if (k & 1) rez += numar(nr);
else rez -= numar(nr);
}
int i;
for (i = last + 1; i <= pr[0]; i++)
if (nr * pr[i] <= 128) back(k + 1, i, nr * pr[i]);
}
int gen(int N)
{
freopen("puteri.in", "w", stdout);
printf("%d\n", N);
int i;
for (i = 1; i <= N; i++) printf("%d %d %d\n", rand() % 64, rand() % 64, rand() % 64);
fclose(stdout);
return 0;
}
int cmmdc(int a, int b)
{
if (a == 0) return b;
if (b == 0) return a;
return cmmdc(b, a % b);
}
void get_brute()
{
int i, j, aa, bb, cc, rez = 0;
for (i = 1; i <= N; i++)
for (j = i + 1; j <= N; j++) {
aa = a[i] + a[j]; bb = b[i] + b[j]; cc = c[i] + c[j];
if (cmmdc(cmmdc(aa, bb), cc) != 1) rez++;
}
printf("%d\n", rez);
}
int main()
{
// gen(100000);
int i;
freopen("puteri.in", "r", stdin);
freopen("puteri.out", "w", stdout);
for (i = 2; i <= 128; i++) if (prim(i)) pr[++pr[0]] = i;
scanf("%d", &N);
for (stepmax = 1; stepmax <= N; stepmax <<= 1); stepmax >>= 1;
for (i = 1; i <= N; i++) scanf("%d %d %d", &a[i], &b[i], &c[i]);
back(0, 0, 1);
printf("%lld\n", rez);
// get_brute();
fclose(stdin);
fclose(stdout);
return 0;
}