zoukankan      html  css  js  c++  java
  • 今日题解------codeforces 895C

    题意:给你一个数列,然后找任意数量的数字(除了空集),使得他们的乘机为一个数的平方

    我们发现元素最大70,所以我们可以从这里入手,平方数有个性质就是它的所有质因子的指数为偶数

    比如:36 = 2*2*3*3;然后我们可以写一个状态压缩dp,第一维表示小于等于第一维的所有数字,第二

    维表示到达的状态,那最终的结果就是dp[70][0],dp[i]和dp[i-1]的区别就是,你有没有取到i这个数字,你会发现,

    如果你取偶数个i的话,对于状态是不影响的,因为偶数个异或就是零,奇数个的话就是它的本身,里面还有一个性质,

    就是C(n,0)+C(n,2) + ... = C(n,1)+C(n,3)+ ...,你可以取a=1,b=-1就很好证明,还有因为它们的和就是

    2的n次方,参考https://zhidao.baidu.com/question/2268538776712429868.html(来自百度),所以无论取奇数个还是偶数,都有

    2的n-1次方种,所以转移方程为if(cnt【i】) dp【i】【j】= (dp【i-1】【j】+ dp【i-1】【s【i】^ j】)*m【cnt【i】-1】;else dp【i】【j】 =dp【i-1】【j】;(还没加入取模运算)

    下面直接看代码:

    #include<bits/stdc++.h>
    #define de(x) cout<<#x<<"="<<x<<endl;
    #define dd(x) cout<<#x<<"="<<x<<" ";
    #define rep(i,a,b) for(int i=a;i<(b);++i)
    #define repd(i,a,b) for(int i=a;i>=(b);--i)
    #define mt(a,b) memset(a,b,sizeof(a))
    #define fi first
    #define se second
    #define inf 0x7f
    #define pii pair<int,int>
    #define pdd pair<double,double>
    #define pdi pair<double,int>
    #define mp(u,v) make_pair(u,v)
    #define sz(a) a.size()
    #define ull unsigned long long
    #define ll long long
    #define pb push_back
    #define PI acos(-1.0)
    const int mod = 1e9+7;
    const int maxn = 1e5+5;
    const double EPS = 1e-6;
    using namespace std;
    int gcd(int a,int b){
        return b==0?a:gcd(b,a%b);
    }
    int a[maxn];
    int s[maxn];
    int prime[maxn];
    ll m[maxn];
    int dp[82][1<<19];
    int cnt[82];
    bool is_prime(int x){
        for(int i=2;i*i<=x;++i) if(x%i==0) return false;
        return true;
    }
    void init(){
        mt(cnt,0);
        int cntt = 0;
        rep(i,2,71){
            if(is_prime(i)) prime[cntt++] = i;
        }
        m[0] = 1;
        rep(i,1,maxn) m[i] = (m[i-1]*2)%mod;
        rep(i,1,71){
            int t = i;
            rep(j,0,19){
                while(t&&t%prime[j]==0){
                     t/=prime[j];
                     s[i] = s[i]^(1<<j);
                }
            }    
        }
    }
    int main()
    {
        init();
        int n;
        scanf("%d",&n);
        rep(i,0,n){
            scanf("%d",&a[i]);
            cnt[a[i]]++;
        }
        dp[0][0] = 1;
        rep(i,1,71){
            rep(j,0,(1<<19)){
                if(cnt[i]){
                    dp[i][j] = ((dp[i-1][j] + dp[i-1][j^s[i]]) %mod) * m[cnt[i]-1]%mod;
                }else dp[i][j] = dp[i-1][j];    
            }
        }
        cout<<((dp[70][0]-1+mod)%mod)<<endl;
        return 0;
    }
  • 相关阅读:
    《你不知道的javascript》读书笔记2
    你不知道的console调试
    《你不知道的javascript》读书笔记1
    使用js做LeetCode
    用装饰器来进行登录验证
    python 解压序列
    pycharm 的live_template的使用
    faker 库的使用
    Python常用内置类和常用内置函数汇总
    迭代器 ,生成器(生成器函数/生成器表达式)
  • 原文地址:https://www.cnblogs.com/chinacwj/p/7967796.html
Copyright © 2011-2022 走看看