2015
09-17

# Coffee shop in Jioufen

Cheer manages a coffee shop in Jioufen. As she is the only assistant in the shop, it is a big problem for her to mix up raw materials into a cup of coffee.
To simplify the problem, we can assume that Cheer has n kinds of raw material, and the i-th raw material has been assigned with a value ai denoting its level of deliciousness.
For some unknown reason, Cheer believe that a kind of coffee is perfect if and only if the value of its all kinds of raw materials are co-prime with each other. A kind of perfect coffee also can be made without any of these raw materials, only by water.
Now given n kinds of raw material and their value of deliciousness, find out how many distinct kinds of perfect coffee can be made by them. Note that two kinds of coffee are considered distinct if and only if the raw material sets of them are distinct.

There are at most 75 test cases.
For each case, The first line contains one integer n indicating the number of kind of raw material.
The next line contains n integers separated by space, denoting deliciousness values: a1, a2, …, an
(1 <= n <= 60, 1 <= ai <= 231-1)
The input ends with n = 0

There are at most 75 test cases.
For each case, The first line contains one integer n indicating the number of kind of raw material.
The next line contains n integers separated by space, denoting deliciousness values: a1, a2, …, an
(1 <= n <= 60, 1 <= ai <= 231-1)
The input ends with n = 0

2
2 2
3
1 2 3
3
2 3 4
0

3
8
6
Hint
For the first case, there 3 distinct kinds of perfect coffee: none of these raw materials, only with the first kind of raw material, and only with the second kind of raw material. Coffee with both the first kind of raw material and the second is not considered as perfect coffee, because the deliciousness levels of first kind of raw material and the second are not co-prime.


#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
#define LL long long
const int maxn =60;
int a[maxn];
LL to[maxn];
int num[maxn];
LL ans;
bool gcd(int a,int b){
return b==0?a!=1:gcd(b,a%b);
}
LL DFS(int n,LL p){
if(n==-1) return 1;
LL res=DFS(n-1,p);
if(p&(1LL<<n)) return res;
if((p|to[n])==p) return res*num[n];
else return res+DFS(n-1,(p|to[n]))*(num[n]-1);
}
int main()
{
int n;
while(~scanf("%d",&n)&&n){
for(int i=0;i<n;i++)
scanf("%d",a+i);
sort(a,a+n);
int m=0;
num[0]=2;
for(int i=1;i<n;i++){
if(a[i]==a[m]) num[m]++;
else { a[++m]=a[i]; num[m]=2; }
}
memset(to,0,sizeof(to));
for(int i=0;i<=m;i++)
{
for(int j=0;j<i;j++)
if(gcd(a[j],a[i]))
to[i]|=1LL<<j;
}
ans=0;
printf("%I64d\n",DFS(m,0));
}
return 0;
}