CF895C Square Subsets
题面传送门
很妙的一道题啊。
这道题看上去很不可做。
然而我们发现\(a_i\leq 70\)
然后我们又发现一些数的乘积为完全平方数那么所有质因数的次数都是\(2\)的倍数。
那么我们可以把所有质因数状压起来扔到线性基里。
线性基外面的全部都是能表示的。
设线性基内元素个数为\(cnt\),则答案为\(2^{n-cnt}-1\)
时间复杂度\(O(na_i)\)
code:
#include<cstdio>
#define N 100039
#define mod 1000000007
#define I inline
using namespace std;
int n,m,k,x,y,z,f[N],cnt,flag[N],pr[N],ph,w=70,now;
I void insert(int x){
for(int i=ph;~i;i--){
if(x&(1<<i)){
if(!f[i]){f[i]=x;cnt++;break;}
x^=f[i];
}
}
}
int main(){
freopen("1.in","r",stdin);
register int i,j;scanf("%d",&n);
for(i=2;i<=w;i++){
if(!flag[i]) pr[++ph]=i;
for(j=1;j<=ph&&pr[j]*i<=w;j++){
flag[pr[j]*i]=1;
if(i%pr[j]==0) break;
}
}
for(i=1;i<=n;i++){
scanf("%d",&x);now=0;
for(j=1;j<=ph;j++){now<<=1;while(x%pr[j]==0) x/=pr[j],now^=1;}insert(now);
}
now=1;for(i=1;i<=n-cnt;i++) now=now*2%mod;printf("%d\n",(now-1+mod)%mod);
}