[高维前缀和] Codeforces 449D - Jzzhu and Numbers
2017-10-06 20:42
351 查看
题意即选一些集合,并为空集的方案数。容易想到容斥
ans=∑i=0220(−1)cnt(i)(2f(i)−1)
其中f(i) 表示包含 i 的集合的个数, cnt(i) 表示 i 中 1 的个数。
现在只需求 f(i) 。f(i)=∑[x & i=i]是个典型的高维前缀和问题。也可以理解成一个简单的 DP 。具体见代码吧。
ans=∑i=0220(−1)cnt(i)(2f(i)−1)
其中f(i) 表示包含 i 的集合的个数, cnt(i) 表示 i 中 1 的个数。
现在只需求 f(i) 。f(i)=∑[x & i=i]是个典型的高维前缀和问题。也可以理解成一个简单的 DP 。具体见代码吧。
#include<cstdio> #include<algorithm> using namespace std; typedef long long LL; const int maxn=1048576+10,M=19,MOD=1000000007; int n,ans,f[maxn]; int Pow(LL a,int b){ LL res=1; for(;b;b>>=1,a=a*a%MOD) if(b&1) res=(res*a)%MOD; return res; } int main(){ scanf("%d",&n); for(int i=1;i<=n;i++){ int x; scanf("%d",&x); f[x]++; } for(int i=0;i<=M;i++) for(int j=0;j<=(1<<M+1)-1;j++) if(!((j>>i)&1)) (f[j]+=f[j|(1<<i)])%=MOD; for(int i=0;i<=(1<<M+1)-1;i++){ int cnt=0; for(int j=0;j<=M;j++) if((i>>j)&1) cnt++; (ans+=((cnt&1)?-1:1)*(Pow(2,f[i])-1))%=MOD; } printf("%d\n",(ans+MOD)%MOD); return 0; }
相关文章推荐
- codeforces 449D - Jzzhu and Numbers 高维前缀和 容斥
- 【高维前缀和+容斥】Codeforces449D[Jzzhu and Numbers]题解
- CodeForces 449 D.Jzzhu and Numbers(状压DP+容斥原理)
- Codeforces 850B - Arpa and a list of numbers(前缀和)
- codeforces-385C Bear and Prime Numbers(素数筛选法+维护前缀和)
- Codeforces 449D:Jzzhu and Numbers
- codeforces 449 D Jzzhu and Numbers(容斥+dp)
- codeforces 851 D. Arpa and a list of numbers(前缀和+bruteforce)
- codeforces 450 B Jzzhu and Sequences
- CodeForces - 449B Jzzhu and Cities
- Codeforces 385 C Bear and Prime Numbers
- CodeForces 449 C.Jzzhu and Apples(构造+数论)
- codeforces 816-B. Karen and Coffee(前缀和+思维)
- Jzzhu and Cities CodeForces - 450D
- codeforces - 450 - B - Jzzhu and Sequences 【简单的矩阵快速幂】
- Codeforces 611C:New Year and Domino 二维前缀和
- Codeforces 449 B. Jzzhu and Cities(图论dijk)
- CodeForces - 519D A and B and Interesting Substrings (前缀和)
- Codeforces 385C Bear and Prime Numbers 筛法
- 【Codeforces 851D Arpa and a list of numbers】