Cod sursa(job #2008117)

Utilizator otto1Palaga Vicentiu-Octavian otto1 Data 5 august 2017 13:43:43
Problema Puteri Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.25 kb
#include <stdio.h>
#include <string.h>

using namespace std;

#define max(a, b) ((a > b) ? a : b)
#define min(a, b) ((a < b) ? a : b)
#define ll long long
#define INF 900000000
#define NMax 100005
#define TMax 65

int N, A[NMax], B[NMax], C[NMax], H[TMax][TMax][TMax], semn[2 * TMax];
int rst[2 * TMax];
ll cnt = 0;

int main(void)
{
    int i, d, nr, x, ok, xmax, m1 = -INF, m2 = -INF, m3 = -INF;
    int r1, r2, r3, rr1, rr2, rr3;
    ll E;

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

    scanf("%d", &N);
    for (i = 1; i <= N; i++)
    {
        scanf("%d %d %d", &A[i], &B[i], &C[i]);

        if (A[i]) m1 = max(m1, A[i]);
        if (B[i]) m2 = max(m2, B[i]);
        if (C[i]) m3 = max(m3, C[i]);
    }
    xmax = min(m1, min(m2, m3)) * 2;

    for (x = 2; x <= xmax; x++)
    {
        i = x; d = 2; nr = 0; ok = 1;
        while (i > 1)
        {
              if (i % d == 0 && (i / d) % d == 0) { ok = 0; break; }
              if (i % d == 0) nr++, i /= d;

              d++;
        }

        if (!ok) { semn[x] = 0; continue ; }

        if (nr % 2 == 1) semn[x] = +1;
        else if (nr % 2 == 0) semn[x] = -1;
    }

    for (x = 2; x <= xmax; x++)
    {
        if (semn[x] == 0) continue;

        // cate perechi au produsul de forma a^x

        memset(H, 0, sizeof(H));

        for (i = 0; i <= 64; i++) rst[i] = i % x;

        for (i = 1; i <= N; i++)
            H[rst[A[i]]][rst[B[i]]][rst[C[i]]]++;

        E = 0;
        for (r1 = 0; r1 <= min(x-1, 64); r1++)
            for (r2 = 0; r2 <= min(x-1, 64); r2++)
                for (r3 = 0; r3 <= min(x-1, 64); r3++)
                {
                    rr1 = x-r1; rr2 = x-r2; rr3 = x-r3;
                    if (rr1 == x) rr1 = 0; if (rr2 == x) rr2 = 0;
                    if (rr3 == x) rr3 = 0;

                    if (rr1 >= 65 || rr2 >= 65 || rr3 >= 65) continue;

                    if (rr1 == r1 && rr2 == r2 && rr3 == r3)
                       E += (ll)(H[r1][r2][r3]-1) * H[r1][r2][r3];
                    else
                       E += (ll)H[r1][r2][r3] * H[rr1][rr2][rr3];

                }

        cnt += E * semn[x];

    }

    printf("%lld\n", cnt / 2);

    return 0;
}