zoukankan      html  css  js  c++  java
  • CodeForces 449D Jzzhu and Numbers 【DP+容斥】

    题目链接:

    http://codeforces.com/contest/449/problem/D

    题意:

    给n个数,求and起来最后为0的集合方案数有多少

    思路:

    http://blog.csdn.net/drcarl/article/details/54616345

    http://www.cnblogs.com/barrier/p/6670514.html?utm_source=itdadao&utm_medium=referral

    先求有多少种情况使得与出来的结果不为0,考察有多少元素在某些二进制位上为1,则它们与出来在这些位上也必然为1。 令函数f(x)为满足ai&x=x的a的个数。 这里的x就是一个bitmask,满足ai&x=x的a,也就意味着这些a在x为1的那些二进制位上为1。 

    那么有了f(x)以后,就可以用容斥原理求出有多少种使得结果不为1的情况。再令g(x)为x的二进制位中1的个数,那么所有结果不为1的情况: 

    上篇博客 是求f(x)的。http://www.cnblogs.com/yxg123123/p/7251206.html

     

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    #define MS(a) memset(a,0,sizeof(a))
    #define MP make_pair
    #define PB push_back
    const int INF = 0x3f3f3f3f;
    const ll INFLL = 0x3f3f3f3f3f3f3f3fLL;
    inline ll read(){
        ll x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    //////////////////////////////////////////////////////////////////////////
    const int maxn = 1e6+10;
    const int mod = 1e9+7;
    
    int n,dp[maxn];
    
    ll qpow(ll a,ll b){
        ll res = 1;
        while(b){
            if(b&1) res = (res*a)%mod;
            a = (a*a)%mod;
            b >>= 1;
        }
        return res;
    }
    
    int main(){
        cin >> n;
        int mx = 0;
        for(int i=1; i<=n; i++){
            int x = read();
            dp[x] ++;
            mx = max(mx,x);
        }
        int bit = 0;
        while(mx){
            mx >>= 1;
            bit++;
        }
        for(int j=0; j<bit; j++){
            for(int i=1; i<maxn; i++)
                if(i & (1<<j))
                    dp[i-(1<<j)] += dp[i];
        }
        dp[0] = n;
        ll ans = qpow(2,n)-1;
        for(int i=1; i<maxn; i++){
            int cnt = 0, t = i;
            while(t) { if(t&1) cnt++; t>>=1;}
            if(cnt&1) ans = (ans-(qpow(2,dp[i])-1)+mod)%mod;
            else ans = (ans+qpow(2,dp[i])-1)%mod;
        }
        cout << ans << endl;
    
        return 0;
    }
  • 相关阅读:
    第十九天:类和对象
    第十五天:模块
    十四天:匿名函数
    十四天作业
    第十三天:迭代器、递归
    十二天:闭包和装饰器
    一个炒鸡简单的购物车
    十一天
    第十天
    第十天作业
  • 原文地址:https://www.cnblogs.com/yxg123123/p/7251318.html
Copyright © 2011-2022 走看看