Cod sursa(job #1333663)

Utilizator chiriacandrei25Chiriac Andrei chiriacandrei25 Data 3 februarie 2015 14:27:06
Problema Puteri Scor 10
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.57 kb
#include <cstdio>
#include <vector>
#define Nmax 100005
#define MOD 100019

using namespace std;

struct triplet
{
    int a,b,c,cnt;
    bool operator == (const triplet A) const
    {
        return (a==A.a && b==A.b && c==A.c);
    }
} v[Nmax],aux[Nmax];
int fr[1000000];
int ciur[130],n;

inline void AH(triplet w)
{
    int key=(10000*w.a+100*w.b+w.c)%MOD;
    ++fr[key];
}

inline void Delete(triplet w)
{
    int key=(10000*w.a+100*w.b+w.c)%MOD;
    --fr[key];
}

inline int SH(triplet w)
{
    int key=(10000*w.a+100*w.b+w.c)%MOD;
    return fr[key];
}

inline long long Count(int p)
{
    triplet w;
    int i;
    long long sol=0;
    for(i=1;i<=n;++i)
    {
        w.a=v[i].a%p; w.b=v[i].b%p; w.c=v[i].c%p;
        aux[i]=w;
        AH(w);
    }
    for(i=1;i<=n;++i)
    {
        w.a=(3*p-aux[i].a)%p; w.b=(3*p-aux[i].b)%p; w.c=(3*p-aux[i].c)%p;
        sol+=SH(w);
        if(w==aux[i]) --sol;
    }
    for(i=1;i<=n;++i) Delete(aux[i]);
    return (sol>>1);
}

int main()
{
    long long ans=0;
    int i,j;
    freopen ("puteri.in","r",stdin);
    freopen ("puteri.out","w",stdout);
    scanf("%d", &n);
    for(i=1;i<=n;++i) scanf("%d%d%d", &v[i].a,&v[i].b,&v[i].c);
    for(i=2;i<=128;++i)
        if(!ciur[i])
        {
            for(j=i*2;j<=128;j+=i) ++ciur[j];
            ans+=Count(i);
        }
        else
        {
            for(j=i*2;j<=128;j+=i) ciur[j]-=(ciur[i]-1);
            if(ciur[i]>1)
                ans-=Count(i)*(ciur[i]-1);
        }
    printf("%lld\n", ans);
    return 0;
}