Cod sursa(job #112251)

Utilizator peanutzAndrei Homorodean peanutz Data 3 decembrie 2007 23:38:33
Problema Puteri Scor 20
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.92 kb
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <vector>

using namespace std;

#define NMAX 130
#define pb push_back
#define sz size()
#define NRMAX 100005

int nr[NMAX][NMAX][NMAX];
vector<int> p, scade, aduna;
int n;
int x[NMAX], y[NMAX], z[NMAX];

void read()
{
    scanf("%d", &n);
    for(int i = 1; i <= n; ++i)
        scanf("%d %d %d\n", &x[i], &y[i], &z[i]);
}

short prim(int x)
{
	int d = 2;
	while(d < x)
	{
		if(!(x%d)) return 0;
		++d;
	}
	return 1;
}
int nrp, a[NMAX];

void get_prime()
{
	p.pb(1);
	for(int i = 2; i < 65; ++i)
		if(prim(i))	
			p.pb(i);
}
	
void back(int k)
{
    for(int crt, j, i = a[k-1]+1; i < nrp; ++i)
    {
        a[k] = i;
        for(j = crt = 1; j <= k; ++j)
            crt *= p[a[j]];
        if(crt <= 128)
        {
            if(k&1)
                aduna.pb(crt);
            else
                scade.pb(crt);
            back(k+1);
        }
    }
}

inline int f(int i, int crt)
{
    i %= crt;
    return (crt-i)%crt;
}

int solve(int crt)
{
    int res = 0, aux = 0;
    for(int i = 0, j, k; i < crt; ++i)
        for(j = 0; j < crt; ++j)
            for(k = 0; k < crt; ++k)
                nr[i][j][k] = 0;
                
    for(int i = 1; i <= n; ++i)
        ++nr[ x[i]%crt ][ y[i]%crt ][ z[i]%crt ];//, printf("%d %d %d\n", x[i]%crt, y[i]%crt, z[i]%crt);

    int ni, nj, nk;
    for(int i = 0, j, k; i < crt; ++i)
        for(j = 0; j < crt; ++j)
            for(k = 0; k < crt; ++k)
            {
                ni = f(i, crt);
                nj = f(j, crt);
                nk = f(k, crt);
                if(ni == i && nj == j && nk == k)
                      aux += nr[i][j][k]*(nr[i][j][k]-1)/2;
                else
                //printf("%d %d %d  %d %d %d  %d\n", i, j, k, ni, nj, nk, nr[i][j][k] * nr[ni][nj][nk]);
                res += nr[i][j][k] * nr[ni][nj][nk];
            }
    return res/2 + aux;
}

int main()
{
	freopen("puteri.in", "r", stdin);
	freopen("puteri.out", "w", stdout);

    read();

	get_prime();
	nrp = p.sz;
	
	back(1);
	
	/*
    sort(aduna.begin(), aduna.end()), sort(scade.begin(), scade.end());
    for(vector<int> :: iterator it = aduna.begin(); it != aduna.end(); ++it)
        printf("%d ", *it); printf("\n");
    for(vector<int> :: iterator it = scade.begin(); it != scade.end(); ++it)
        printf("%d ", *it); printf("\n");
    return 0;
    */

    //printf("%d\n", solve(2));
    //return 0;
    int res = 0;
    for(vector<int> :: iterator it = aduna.begin(); it != aduna.end(); ++it)
        res += solve(*it);//, printf("%d %d\n", *it, solve(*it));

    for(vector<int> :: iterator it = scade.begin(); it != scade.end(); ++it)
        res -= solve(*it);//, printf("%d %d\n", *it, solve(*it));
        
    printf("%d\n", res);

	return 0;
}