Cod sursa(job #95496)

Utilizator stef2nStefan Istrate stef2n Data 29 octombrie 2007 00:29:57
Problema Indep Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.15 kb
/*
 *		Principiul includerii si al excluderii
 *		Complexitate: O(1000 * max(N, LUNG_MAX))
 */

#include <cstdio>

#define CMAX 160
#define NMAX 505
struct BigNumber {short int N, x[CMAX];};

int N, val[NMAX];
BigNumber P[NMAX];
BigNumber plus, minus;

BigNumber unitate()
{
	BigNumber A;
	A.N=A.x[0]=1;
	return A;
}

int desc(int x)
{
	int x_ini=x, p=2, cnt=0, f;
	while(x>1 && p*p<=x_ini)
	{
		f=0;
		while(x%p==0)
		{
			x/=p;
			f++;
		}
		if(f>1)
			return -1;
		if(f==1)
			cnt++;
		p++;
	}
	if(x>1)
		cnt++;
	return cnt;
}

void read_data()
{
	scanf("%d",&N);
	for(int i=0; i<N; ++i)
		scanf("%d",&val[i]);
}

BigNumber produs2(BigNumber A)
{
	BigNumber B;
	short int in_minte=0;
	for(B.N=0; B.N<A.N || in_minte; ++B.N)
	{
		B.x[B.N]=(B.N<A.N)*A.x[B.N]*2+in_minte;
		in_minte=B.x[B.N]/10;
		B.x[B.N]%=10;
	}
	return B;
}

BigNumber sum(BigNumber A, BigNumber B)
{
	BigNumber C;
	int in_minte=0;
	for(C.N=0; C.N<A.N || C.N<B.N || in_minte; ++C.N)
	{
		C.x[C.N]=(C.N<A.N)*A.x[C.N]+(C.N<B.N)*B.x[C.N]+in_minte;
		in_minte=C.x[C.N]/10;
		C.x[C.N]%=10;
	}
	return C;
}

BigNumber dif(BigNumber A, BigNumber B)
{
	BigNumber C;
	int imprumut=0;
	for(C.N=0; C.N<A.N; ++C.N)
		if(A.x[C.N]-(C.N<B.N)*B.x[C.N]-imprumut<0)
		{
			C.x[C.N]=10+A.x[C.N]-(C.N<B.N)*B.x[C.N]-imprumut;
			imprumut=1;
		}
		else
		{
			C.x[C.N]=A.x[C.N]-(C.N<B.N)*B.x[C.N]-imprumut;
			imprumut=0;
		}
	return C;
}

void init()
{
	P[0].N=P[0].x[0]=1;
	for(int i=1; i<=N; ++i)
		P[i]=produs2(P[i-1]);
	plus.N=minus.N=1;
	plus.x[0]=minus.x[0]=0;
}

void write(BigNumber A)
{
	int i=A.N-1;
	while(i>=0 && A.x[i]==0)
		--i;
	if(i==-1)
		printf("0");
	for(;i>=0;--i)
		printf("%d",A.x[i]);
	printf("\n");
}

void solve()
{
	plus=P[N];
	minus=unitate();
	for(int i=2; i<=1000; ++i)
	{
		int nr=desc(i);
		if(nr!=-1)
		{
			int cnt=0;
			for(int j=0; j<N; ++j)
				if(val[j]%i==0)
					cnt++;
			if(cnt)
				if(nr&1)
				{
					plus=sum(plus,unitate());
					minus=sum(minus,P[cnt]);
				}
				else
				{
					plus=sum(plus,P[cnt]);
					minus=sum(minus,unitate());
				}
		}
	}
}


int main()
{
	freopen("indep.in","r",stdin);
	freopen("indep.out","w",stdout);
	read_data();
	init();
	solve();
	write(dif(plus,minus));
	return 0;
}