Cod sursa(job #248853)

Utilizator andrei-alphaAndrei-Bogdan Antonescu andrei-alpha Data 26 ianuarie 2009 22:11:08
Problema Puteri Scor 10
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.47 kb
using namespace std;

#include <set>
#include <map>
#include <list>
#include <deque>
#include <stack>
#include <queue>
#include <cmath>
#include <cstdio>
#include <vector>
#include <string>
#include <bitset>
#include <utility>
#include <algorithm>

#define pb push_back
#define sz size
#define f first
#define s second
#define II inline
#define ll long long
#define db double
#define FOR(i,a,b) for(int i=a;i<=b;++i)
#define all(v) v.begin() , v.end()
#define CC(v) memset((v),0,sizeof((v)))
#define CP(v,w) memcpy((v),(w),sizeof((w)))
#define mp make_pair

#define IN  "puteri.in"
#define OUT "puteri.out"
#define N_MAX 1<<17
#define MOD 65535

typedef vector<int> VI;
typedef pair<int,int> pi;
typedef vector<string> VS;

int mod,N,P[1<<7];
int NR[1<<7],A[1<<7],V[N_MAX];
vector<bool> viz(1<<8);
vector<bool> bo(1<<8);

II void ciur()
{
	for(int i=4;i<=(1<<7);i+=2)
		viz[i] = true;
	P[++P[0]] = 2;
	
	for(int i=3;i<=(1<<7);i+=2)
	{
		if(viz[i])
			continue;
		P[++P[0]] = i;
		for(int j=i+i;j<=(1<<7);j+=i)
			viz[j] = true;
	}	
}

II void scan()
{
	freopen(IN,"r",stdin);
	freopen(OUT,"w",stdout);
	
	scanf("%d",&N);
	int a,b,c;
	FOR(i,1,N)
	{
		scanf("%d %d %d",&a,&b,&c);
		V[i] = a * 10000 + b * 100 + c;
	}	
}

II void make(int &a,int &b,int &c,int x)
{
	c = x % 100;
	b = (x / 100) % 100;
	a = (x / 10000);
	
	a = a % mod;
	b = b % mod;
	c = c % mod;
}

II bool divide(int x)
{
	int nr(0),aux = x;
	for(int i=2;i*i<=x;++i)
	{
		if(aux % i)
			continue;
		++nr;
		aux /= i;
		if(!(aux % i) || !bo[i])
			return false;	
	}	
	if(aux>1)
		++nr;
	NR[x] = nr;
	return true;
}

II void solve()
{
	int a,b,c;
	int C[64][64][64];
	
	FOR(pi,1,128)
	{
		mod = pi;//P[pi];
		if(!viz[mod])
			NR[mod] = 1;
		if(viz[mod] && !divide(mod) )
			continue;
		for(int i=N-1;i>=1;--i)
		{
			make(a,b,c,V[i+1]);
			if(V[i+1])
				++C[a][b][c];
			
			make(a,b,c,V[i]);
			if(mod-a<64 && mod-b < 64 && mod-c < 64)
				A[mod] += C[ (a?mod-a:0) ][ (b?mod-b:0) ][ (c?mod-c:0) ]; 
		}
		if(A[mod])
			bo[mod] = true;
		
		CC(C);
	}
	
//	FOR(i,4,128)
//		if(viz[i])
//			divide(i);
	
	ll rez(0);	
	FOR(i,2,128)
	{
		if(NR[i]&1)
		{
		//	if(A[i])
		//		printf("pe %d il adunam %d\n",i,A[i]);	
			rez += A[i];
		}	
		else
		{
		//	if(A[i])
		//		printf("pe %d il scadem %d\n",i,A[i]);	
			rez -= A[i];
		}	
	}	
	printf("%lld\n",rez);
}

int main()
{
	ciur();
	scan();
	solve();
	
	return 0;
}