Cod sursa(job #920277)

Utilizator apopeid13Apopeid Alejandro apopeid13 Data 20 martie 2013 10:05:13
Problema Puteri Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.24 kb
# include <cstdio> 
# include <cstring> 
  
const char *FIN = "puteri.in", *FOU = "puteri.out" ; 
const int MAX = 65; 
  
unsigned char V[1 << 5]; 
int N, cnt[MAX][MAX][MAX], CNT[MAX][MAX][MAX], prim[MAX << 1], st[MAX << 1] ; 
long long solution ; 
  
inline void rec (int lev, int K, int pr, int see) { 
    if (pr > (MAX << 1) - 2) return ; 
    if (lev == K) { 
        memset (CNT, 0, sizeof (CNT)); 
        for (int a = 0; a < MAX; ++a) { 
            for (int b = 0; b < MAX; ++b) { 
                for (int c = 0; c < MAX; ++c) { 
                    CNT[a % pr][b % pr][c % pr] += cnt[a][b][c]; 
                } 
            } 
        } 
        for (int a = 0; a < MAX && a < pr; ++a) { 
            for (int b = 0; b < MAX && b < pr; ++b) { 
                for (int c = 0; c < MAX && c < pr; ++c) { 
                    int A = (pr - a) % pr, B = (pr - b) % pr, C = (pr - c) % pr; 
                    if (A > MAX - 1 || B > MAX - 1 || C > MAX - 1) continue ; 
                    solution += see * 1LL * CNT[a][b][c] * (CNT[A][B][C] - (a == A && b == B && c == C)); 
                } 
            } 
        } 
        return ; 
    } 
    for (int i = (lev > 0 ? st[lev - 1] + 1 : 1); i <= prim[0]; ++i) { 
        st[lev] = i; 
        rec (lev + 1, K, pr * prim[i], see) ; 
    } 
} 
  
int main (void) { 
    freopen (FIN, "r", stdin) ; 
  
    scanf ("%d", &N) ; 
    for (int i = 0, a, b, c; i < N; ++i) { 
        scanf ("%d %d %d", &a, &b, &c); 
        ++cnt[a][b][c]; 
    } 
  
    for (int i = 1; ( i * i << 1 ) + ( i << 1 ) <= MAX << 1; ++i) { 
        if ( ( V[i >> 3] & ( 1 << ( i & 7 ) ) ) == 0 ) { 
            for (int j = ( i * i << 1 ) + ( i << 1 ); ( j << 1 ) + 1 <= MAX << 1; j += ( i << 1 ) + 1) 
                V[j >> 3] |= ( 1 << ( j & 7 ) ); 
        } 
  
    } 
    prim[++prim[0]] = 2; 
    for (int i = 1; ( i << 1 ) + 1 <= MAX << 1; ++i) { 
        if ( ( V[i >> 3] & ( 1 << ( i & 7 ) ) ) == 0 ) 
            prim[++prim[0]] = (i << 1) + 1; 
    } 
    for (int i = 1, pr = 1; i <= prim[0]; ++i) { 
        pr *= prim[i]; 
        if (pr > (MAX << 1) - 2) break ; 
        rec (0, i, 1, (i & 1 ? 1 : -1)) ; 
    } 
    fprintf (fopen (FOU, "w"), "%lld", solution >> 1) ; 
}