题目链接:http://codeforces.com/contest/895/problem/C
70以内就19个素数,直接状压,0表示出现偶数次,1表示出现奇数次,然后对于每个数枚举选取奇数次还是偶数次,T了一发随便改改就过了,其实好像可以处理出2的幂次来搞啊?貌似那样就是稳定7e7的复杂度哦?绝望。。。
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MOD=1e9+7;
const int MAXN=(1<<20)+5;
int prime[100],pool[100];//保存素数
bool vis[100];//初始化
int cnt=0;
ll qpow(ll a,ll b)
{
ll ans=1;a%=MOD;
for(ll i=b;i;i>>=1,a=a*a%MOD)
if(i&1)ans=ans*a%MOD;
return ans;
}
void Prime(int n=MAXN)
{
memset(vis,0,sizeof(vis));
for(int i=2;i<n;i++)
{
if(!vis[i])
prime[cnt++]=i;
for(int j=0;j<cnt&&i*prime[j]<n;j++)
{
vis[i*prime[j]]=1;
if(i%prime[j]==0)//关键
break;
}
}
for(int i=1;i<=70;i++)
{
int x=i;
for(int j=0;j<cnt&&prime[j]<=x;j++)
{
while(x%prime[j]==0)
{
pool[i]^=(1<<j);
x/=prime[j];
}
}
}
}
int num[100];
ll dp[2][MAXN];
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
Prime(70);
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
int x;
scanf("%d",&x);
num[x]++;
}
int now=0,nxt=1;
dp[now][0]=1;
for(int i=1;i<=70;i++)
{
if(num[i]==0)
continue;
memset(dp[nxt],0,sizeof(dp[nxt]));
for(int j=0;j<MAXN;j++)
{
if(dp[now][j])
{
dp[nxt][j]=(dp[nxt][j]+qpow(2,num[i]-1)*dp[now][j])%MOD;
dp[nxt][j^pool[i]]=(dp[nxt][j^pool[i]]+qpow(2,num[i]-1)*dp[now][j])%MOD;
}
}
now^=1;nxt^=1;
}
printf("%lld\n",dp[now][0]-1);
return 0;
}