zoukankan      html  css  js  c++  java
  • Codeforces 895C

    895C - Square Subsets

    思路:状压dp。

    每个数最大到70,1到70有19个质数,给这19个质数标号,与状态中的每一位对应。

    状压:一个数含有这个质因子奇数个,那么他状态的这一位是1,一个数含有这个这个质因子偶数个,那么状态的这一位是0。

    那么如果一个数是平方数,那么这个数的状态每一位都是0,即状态为0。

    状态转移见代码。

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define pb push_back
    #define mem(a,b) memset(a,b,sizeof(a))
    
    const int N=1e5+5;
    const int MOD=1e9+7;
    int a[N];
    int cnt[75];
    int dp[75][(1<<19)+5];
    int s[75];
    int prime[19]={2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67};
    int _2p[N];
    int main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0);
        for(int i=1;i<=70;i++)
        {
            int t=i;
            for(int j=0;j<19;j++)
            {
                while(t%prime[j]==0)t/=prime[j],s[i]^=(1<<j);
            }
        }
        _2p[0]=1;
        for(int i=1;i<N;i++)_2p[i]=(_2p[i-1]*2)%MOD;
        int n;
        cin>>n;
        for(int i=1;i<=n;i++)cin>>a[i],cnt[a[i]]++;
        dp[0][0]=1;
        for(int i=1;i<=70;i++)
        {
            if(!cnt[i])
            {
                for(int j=0;j<(1<<19);j++)
                dp[i][j]=dp[i-1][j];
            }
            else
            {
                for(int j=0;j<(1<<19);j++)
                {
                    dp[i][j^s[i]]=((ll)dp[i][j^s[i]]+(ll)_2p[cnt[i]-1]*dp[i-1][j])%MOD;//从cnt[i]个数个选奇数个,C(n,1)+C(n,3)+...=2^(n-1)
                    dp[i][j]=((ll)dp[i][j]+(ll)_2p[cnt[i]-1]*dp[i-1][j])%MOD;//从cnt[i]个数个选偶数个,C(n,0)+C(n,2)*C(n,4)+...=2^(n-1)
                }
            }
        }
        cout<<(dp[70][0]-1)%MOD<<endl;//减去0的情况
    return 0; }
  • 相关阅读:
    12个非常不错的javascript类库
    CSS中单位em和rem的区别
    CSS中box-sizing属性的作用
    网页设计中的默认字体样式详解
    jQuery遍历Table表格的行和列
    css常用解决方案
    JS判断字符串小括号是否成对合法
    Less编码规范
    React九宫格抽奖
    n个有序数组,取出k个最大值
  • 原文地址:https://www.cnblogs.com/widsom/p/7910385.html
Copyright © 2011-2022 走看看