题意:n个由2000以内素数乘积的数,问任意选至少一个数,乘积是完全平方数的个数是多少。
分析:每个数都可以由质数唯一分解,然后设取a[i] x[i]个然后就可以列一个方程,因为是完全平方数,所以只要个数是0 (mod2)就好,xi前的系数也mod2最后解出自由变元数p 答案就是2^p
#include<bits/stdc++.h>
#define mod 1000000007
using namespace std;
bool vis[2222];
int prime[333];
int cnt;
long long v[333];
int a[333][333];
long long two[333];
void init(void) {
memset(vis,0,sizeof vis);
int tt=0;
vis[1]=1;
for(int i=2;i<=2000;i++) {
if(vis[i]==0) {
prime[++tt]=i;
for(int j=i+i;j<=2000;j+=i) vis[j]=1;
}
}
cnt=tt;
two[0]=1;
for(int i=1;i<=300;i++)
two[i]=two[i-1]*2%mod;
}
void swapl(int x,int y,int n) {
int tt;
for(int i=1;i<=n;i++) {
tt=a[x][i];
a[x][i]=a[y][i];
a[y][i]=tt;
}
}
int Guass(int n) {
int ps=0;
for(int i=1;i<=n;i++) {
int k=0;
for(int j=i-ps;j<=cnt;j++) {
if(a[j][i]==1) {
k=j;
break;
}
}
if(k==0) {
ps++;
continue;
}
if(k!=i-ps) {
swapl(k,i-ps,n);
}
for(int j=i+1-ps;j<=cnt;j++) {
if(a[j][i]==1)
for(int u=i;u<=n+1;u++)
a[j][u]^=a[i-ps][u];
}
}
// cout << "ps==="<<ps << endl;
return n-ps;
}
int main()
{
init();
int t,n;
int kase=0;
scanf("%d",&t);
while(t--) {
scanf("%d",&n);
for(int i=1;i<=n;i++) {
scanf("%lld",&v[i]);
}
for(int i=1;i<=n;i++) {
for(int j=1;j<=cnt;j++) {
a[j][i]=0;
if(v[i]%prime[j]==0) {
while(v[i]%prime[j]==0) {
a[j][i]^=1;
v[i]/=prime[j];
}
}
}
}
/* for(int i=1;i<=n;i++) {
for(int j=1;j<=4;j++) {
cout << a[i][j] << " ";
}
cout << endl;
}*/
int r=Guass(n);
/* cout << "------------" << endl;
for(int i=1;i<=n;i++) {
for(int j=1;j<=4;j++) {
cout << a[i][j] << " ";
}
cout << endl;
}*/
int tmp=n-r;
printf("Case #%d:\n%lld\n",++kase,(two[tmp]-1+mod)%mod);
}
return 0;
}