Codeforces Round #448 (Div. 2) C. Square Subsets(状压)

来源:互联网 发布:java图书销售管理系统 编辑:程序博客网 时间:2024/06/05 08:00

题目链接: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;}


阅读全文
0 0