# POJ 3904-Sky Code 容斥原理

AC代码：

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
using namespace std;

typedef long long ll;
const int maxn = 10005;

ll prime[maxn], p[maxn], num[maxn], count[maxn];
void init()
{
memset(p, 0, sizeof(p));
memset(num, 0, sizeof(num));
for(ll i = 4; i < maxn; i++){
p[i] = i*(i-1)*(i-2)*(i-3)/24;
}
}

void solve(int n)
{
int cnt = 0;
for(int i = 2; i*i <= n; i++){
if(n % i == 0){
prime[cnt++] = i;
n /= i;
}
while(n % i == 0){
n /= i;
}
}
if(n != 1)	prime[cnt++] = n;
for(int i = 1; i < (1 << cnt); i++){	//	以二进制形式来枚举
int k = 1, sum = 0;
for(int j = 0; j < cnt; j++){
if(i & (1<<j)){
k *= prime[j];
sum++;
}
}
count[k]++;
num[k] = sum;
}
}

int main()
{
init();
int n, m;
while(~scanf("%d", &n)){
memset(count, 0, sizeof(count));
for(int i = 0; i < n; i++){
scanf("%d", &m);
solve(m);
}
ll ans = 0;
for(int i = 0; i < maxn; i++){
if(count[i]){
if(num[i]&1)
ans += p[count[i]];
else	ans -= p[count[i]];
}
}
cout << p[n] - ans << endl;
}
return 0;
}