zoukankan      html  css  js  c++  java
  • Codeforces 449D Jzzhu and Numbers

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

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

    思路:考虑容斥,ans=(-1)^k*num(k),num(k)代表至少有k个数字and起来为1的方案数,那么怎么求num呢?

    考虑and起来至少为x的方案数:那么一定是2^y-1,其中y代表有多少个数&x==x,问题就变成有多少数"包含"了某个数(二进制下),用dp解决这个问题:如果某一位数字是1,那么它一定能转移到它不是1的那个位置。

    即:f[i]+=f[i|(1<<j)]

    注意循环,如果两层的循环换一下位置就会重复计数了。

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #define ll long long
    const ll Mod=1000000007;
    ll f[2000005],bin[2000005];
    int n;
    int read(){
        int t=0,f=1;char ch=getchar();
        while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
        while ('0'<=ch&&ch<='9'){t=t*10+ch-'0';ch=getchar();}
        return t*f;
    }
    void solve(){
       for (int j=0;j<20;j++)
        for (int i=0;i<=1000000;i++)
            if ((1<<j)&i) (f[i^(1<<j)]+=f[i])%=Mod;
        ll ans=0;        
        for (int i=0;i<=1000000;i++){
            int cnt=1;
            for (int j=0;j<20;j++)
                if ((1<<j)&i) cnt=-cnt;
            ans=((ans+(cnt*(bin[f[i]]-1)%Mod))%Mod+Mod)%Mod;        
        }        
        printf("%I64d
    ",ans);
    }
    int main(){
        n=read();
        bin[0]=1;
        for (int i=1;i<=1000000;i++) bin[i]=(bin[i-1]*2)%Mod;
        for (int i=1;i<=n;i++) f[read()]++;
        solve();
    }
  • 相关阅读:
    pet shop 案例(转)
    用我账号的哥们 别随意留言 谢谢 这个账号有特殊意义
    关于if else 和 switch 的区别 究竟哪个更快
    sql server 2008 保存表的设置
    shell编程
    敏捷项目管理
    日常起居六忌是什么?
    质量管理的几个陌生词汇
    阿里巴巴一名员工的辞职信
    什么是SaaS?
  • 原文地址:https://www.cnblogs.com/qzqzgfy/p/5662875.html
Copyright © 2011-2022 走看看