tystrwor的博客

。。。

Codeforces D. Jzzhu and Numbers 【容斥+高维前缀和】

题目传送门
【考查点:容斥原理的理解,高维前缀和求解】
题意:给 n(n<=1e6) 个数,每个数都小于等于1e6, 求其中取任意个数&值为0的方案数?
题解:我们先求解&和不为零的情况。我们令d[x]ai&x==x 的所有ai 数目。对于每个 xd[x] 它们中任意取数&和都不为零。其方案数为(2f(x)1)
根据容斥原理所有&和不为0的方案数为

i=11e6(1)g(x)+1(2f(x)11)

ans=2n1i=11e6(1)g(x)+1(2f(x)11)

由于f(0)==n

ans=i=01e6(1)g(x)(2f(x)11)

然后求解f(x)过程就是一个求解高维前缀和过程。

ACcode

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int MOD=1e9+7;
const int N=1<<20;
int d[N];
LL p[N];
int bt[25],n,x;
int main()
{
    for(int i=0;i<=20;i++)bt[i]=1<<i;
    p[0]=1;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&x);
        d[x]++;
        p[i]=p[i-1]<<1;
        if(p[i]>=MOD)
            p[i]-=MOD;
    }
       for(int j=0;j<=20;j++)
        for(int i=0;i<=1000000;i++)
        {
            if(i&bt[j])
                d[i^bt[j]]+=d[i];
        }
    LL ans=0,cur;
    for(int i=0;i<=1000000;i++)
    {
        if(d[i])
        {
            cur=p[d[i]]-1;
            if(__builtin_popcount(i)&1)
                ans=(ans+MOD+MOD-cur)%MOD;
            else
                ans=(ans+cur)%MOD;
        }
    }
    printf("%lld\n",ans);
}
阅读更多
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/m0_37953323/article/details/79973285
上一篇HBCPC 2018 网络赛H 【分块】
下一篇CodeForces - 501E Misha and Palindrome Degree
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭