Cod sursa(job #199691)

Utilizator toni2007Pripoae Teodor Anton toni2007 Data 20 iulie 2008 10:01:16
Problema Pairs Scor 0
Compilator c Status done
Runda Arhiva de probleme Marime 1.87 kb
#define task "pairs"
#define score 100
#define fin  "pairs.in"
#define fout "pairs.out"
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define MAX 1<<20
#define N 1<<17
#define bool char
#define true 1
#define false 0
bool set[MAX];
int v[N];
int n;
long long sol,res;
int x[N];
int stack[2*N];
int max=-1;
bool ci[MAX];
inline void insert(int x){
	set[x]=true;
}
void scan(void){
	int i;
	freopen(fin, "r",stdin );
	freopen(fout,"w",stdout);
	scanf("%d",&n);
	for (i=1;i<=n;++i){
		scanf("%d",&v[i]);
		insert(v[i]);
		if (v[i]>max)
			max=v[i];
	}
}
void push(int x){
	stack[++stack[0]]=x;
}
void ciur(void){
	int i,j;
	ci[0]=ci[1]=1;
	for (i=4;i<=max;i+=2)
		ci[i]=1;
	for (i=3;i<=floor(sqrt(max));i+=2)
		if (!ci[i])
			for (j=i*i;j<=max;j+=i)
				ci[j]=1;
	stack[0]=0;
	push(2);
	for (i=3;i<=max;i+=2)
		if (!ci[i])
			push(i);
	//for (i=1;i<=stack[0];++i)
		//printf("c%d ",stack[i]);
}
void verif(int last,int cat){
	long long aux;
	if (cat==0)
		return;
	//last=stack[last];
	aux=x[last];
	aux*=x[last]-1;
	aux/=2;
	if (cat%2==1)
		res+=aux;
	else
		res-=aux;
}
void back(int last,int now,int max,int cat){
	//printf("%d %d %d %d\n",last,now,max,cat);
	verif(last,cat);
	if ((long long)last*stack[now]>(long long)max){
		return;
	}
	while ((long long)last*stack[now]<=(long long)max && now<=stack[0]){
		back(last*stack[now],now+1,max,cat+1);
		++now;
	}
}
void solve(void){
	int i,j;
	sol=(long long)n*(n-1)/2;
	/*.........................................*/
	for (i=1;i<=max;++i)
		for (j=i;j<=max;j+=i)
			if (set[j])
				++x[i];
	/*.........................................*/
	ciur();
	///for (i=1;i<=max;++i)
		//printf("%d ",x[i]);
	back(1,1,max,0);
}
void print(void){
	printf("%lld\n",sol-res);
	//fprintf(stderr,"%lld\n",sol-res);
	exit(0);
}
int main(void){
	scan();
	solve();
	print();
}