链接
题意
给你一个长度为\(n\)的序列\(a\),并且对于任意一个数\(a[i]\),它只有小于\(50\)的素因子,且不含有平方因子,求有多少对\((i,j)\),使得\(a[i]和a[j]\)互质,或者\(gcd\)是质数。
输入格式:第一行输入\(t\),包含\(t\)组样例,下面每组样例第一行一个\(n\),下面一行输入一个长度为\(n\)的序列\(a\)。
数据范围:\(1\leq t\leq 10,1\leq 100000\).
输出格式:每个样例对应一行一个输出结果。
分析
这一题是偶然在别人博客看到的,几乎没怎么写过数学题,感到这个思路非常非常的巧妙。
首先考虑到了\(50\)以内的素数仅有\(15\)个,而对于\(a\)序列中的任意两个数来说,它们的\(gcd\)要么为\(1\),要么在这\(15\)个素数之中,要么为\(1\),如果用二进制表示,那么则有它们二进制表示的与的结果为\(0\),或者某一位为\(1\)(恰好有一个素因子)。对于一个二进制表示\(i\)来说,我们需要求出它的个数与,它补集的子集个数的乘积,这即是求出了\(gcd\)为\(1\)的情况,对于不为\(1\)的情况,我们求出它与,它的补集对某一位\(0\)取反变成\(1\)的所有子集个数在减去它补集没去反之间子集的个数,这二者乘积,对所有的状态进行累加。
关键是如何快速求子集个数,对于\(i\),求所有的\(j\),\(j\leq i \&\&(i|j)==i\)。网上代码为:
1 | for(i=0;i<M;i++){ |
代码
1 |
|