/*
poj 3904
题意大体是
给你n个数
问在这n个数中找4个没有公约数的数
有多少组
※ 4个数没有公约数不代表两两互质
比如 2 3 4 5
2和4就不互质但他们四个没有公约数
由于直接求没有公约数的组数比较复杂
我们可以先算有公约数的组数
因此需要将N个数每个数质因数分解
纪录下所有不同的素因子所能组成的因子(就是4个数的公约数)
并统计构成每种因子的素因子个数和因子总数
然后再计算组合数
比如说
因子2的个数为a,则四个数公约数为2的个数为C(a,4)
因子3的个数为b,则四个数公约数为3的个数为C(b,4)
因子6(2*3)的个数为c,则四个数公约数为6的个数为C(c,4)。
但是公约数为2的情况中或者公约数为3的情况中可能包括公约数为6的情况
所以我们要用到容斥原理
*/
#include<iostream>
#include<algorithm>
#include<string.h>
#include<string>
#include<stdio.h>
#include<math.h>
#define ll long long
#define INF 2147483647
#define N 10005
#define PI acos(-1)
#define EPS 1e-8
using namespace std;
ll prime[N],co[N],p[N],num[N];
void init()
{
memset(p,0,sizeof(p));
memset(num,0,sizeof(num));
for(ll i=4;i<N;i++)
p[i]=i*(i-1)*(i-2)*(i-3)/24;
}
void work(int n)
{
int top=0;
for(int i=2;i*i<=n;i++)
{
if(n%i)
continue;
while(n%i==0)
n=n/i;
prime[top++]=i;
}
if(n>1)
prime[top++]=n;
for(int i=1;i<(1<<top);i++)
{
int tmp=1,cnt=0;
for(int j=0;j<top;j++)
{
if(((i>>j)&1)==0)
continue;
tmp*=prime[j];
cnt++;
}
co[tmp]++;
num[tmp]=cnt;
}
}
int main()
{
init();
int n;
while(cin>>n)
{
memset(co,0,sizeof(co));
for(int i=1;i<=n;i++)
{
int res;
cin>>res;
work(res);
}
ll sum=0;
for(int i=0;i<N;i++)
{
if(!co[i])
continue;
if(num[i]%2)
sum+=p[co[i]];
else
sum-=p[co[i]];
}
cout<<p[n]-sum<<endl;
}
return 0;
}
poj 3904
题意大体是
给你n个数
问在这n个数中找4个没有公约数的数
有多少组
※ 4个数没有公约数不代表两两互质
比如 2 3 4 5
2和4就不互质但他们四个没有公约数
由于直接求没有公约数的组数比较复杂
我们可以先算有公约数的组数
因此需要将N个数每个数质因数分解
纪录下所有不同的素因子所能组成的因子(就是4个数的公约数)
并统计构成每种因子的素因子个数和因子总数
然后再计算组合数
比如说
因子2的个数为a,则四个数公约数为2的个数为C(a,4)
因子3的个数为b,则四个数公约数为3的个数为C(b,4)
因子6(2*3)的个数为c,则四个数公约数为6的个数为C(c,4)。
但是公约数为2的情况中或者公约数为3的情况中可能包括公约数为6的情况
所以我们要用到容斥原理
*/
#include<iostream>
#include<algorithm>
#include<string.h>
#include<string>
#include<stdio.h>
#include<math.h>
#define ll long long
#define INF 2147483647
#define N 10005
#define PI acos(-1)
#define EPS 1e-8
using namespace std;
ll prime[N],co[N],p[N],num[N];
void init()
{
memset(p,0,sizeof(p));
memset(num,0,sizeof(num));
for(ll i=4;i<N;i++)
p[i]=i*(i-1)*(i-2)*(i-3)/24;
}
void work(int n)
{
int top=0;
for(int i=2;i*i<=n;i++)
{
if(n%i)
continue;
while(n%i==0)
n=n/i;
prime[top++]=i;
}
if(n>1)
prime[top++]=n;
for(int i=1;i<(1<<top);i++)
{
int tmp=1,cnt=0;
for(int j=0;j<top;j++)
{
if(((i>>j)&1)==0)
continue;
tmp*=prime[j];
cnt++;
}
co[tmp]++;
num[tmp]=cnt;
}
}
int main()
{
init();
int n;
while(cin>>n)
{
memset(co,0,sizeof(co));
for(int i=1;i<=n;i++)
{
int res;
cin>>res;
work(res);
}
ll sum=0;
for(int i=0;i<N;i++)
{
if(!co[i])
continue;
if(num[i]%2)
sum+=p[co[i]];
else
sum-=p[co[i]];
}
cout<<p[n]-sum<<endl;
}
return 0;
}