题解 CF895C 【Square Subsets】
我们设 \(x=\prod p_i^{k_i}\),考虑什么时候 \(x\) 是完全平方数。容易发现如果所有 \(k_i\) 都是偶数,此时 \(\sqrt{x}=\prod p_i^{\frac{k_i}{2}}\) 为整数,即 \(x\) 是完全平方数;否则 \(x\) 不是完全平方数。
题目转换为原序列 \(\{a_i\}\) 有多少个非空子集乘积质因数分解后质数均为偶数。
发现奇偶性是满足异或性质的,奇数对应 \(1\),偶数对应 \(0\)。考虑将原序列的每一个 \(a_i\) 进行质因数分解,将分解后每个质因数的指数奇偶性二进制压位成一个整数,存到线性基中。
假设线性基中有 \(cnt\) 个元素,那么剩下的 \(n-cnt\) 个数可以用线性基的元素异或表示,可以任意取,共有 \(2^{n-cnt}\) 种取法,注意减掉全都不取的一种就是答案。
//By: Luogu@rui_er(122461)
#include
#define rep(x,y,z) for(int x=y;x<=z;x++)
#define per(x,y,z) for(int x=y;x>=z;x--)
#define debug printf("Running %s on line %d...\n",__FUNCTION__,__LINE__)
#define fileIO(s) do{freopen(s".in","r",stdin);freopen(s".out","w",stdout);}while(false)
using namespace std;
typedef long long ll;
const int N = 1e5+5, mod = 1e9+7;
const int pm[] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67};
int n, a[N];
template void chkmin(T& x, T y) {if(x > y) x = y;}
template void chkmax(T& x, T y) {if(x < y) x = y;}
struct LinearBasis {
int p[19];
LinearBasis() {memset(p, 0, sizeof(p));}
~LinearBasis() {}
void insert(int x) {
per(i, 18, 0) {
if(!((x >> i) & 1)) continue;
if(!p[i]) {p[i] = x; return;}
x ^= p[i];
}
}
int qmax() {
int ans = 0;
per(i, 18, 0) chkmax(ans, ans^p[i]);
return ans;
}
int cnt() {
int ans = 0;
per(i, 18, 0) ans += !!p[i];
return ans;
}
}LB;
int qpow(int x, int y) {
int ans = 1;
for(;y;y>>=1,x=1LL*x*x%mod) if(y & 1) ans = 1LL * ans * x % mod;
return ans;
}
int main() {
scanf("%d", &n);
rep(i, 1, n) {
scanf("%d", &a[i]);
int now = 0;
per(j, 18, 0) {
now <<= 1;
while(!(a[i] % pm[j])) {
now ^= 1;
a[i] /= pm[j];
}
}
LB.insert(now);
}
printf("%d\n", (qpow(2, n-LB.cnt())+mod-1)%mod);
return 0;
}