Codeforces 449D:Jzzhu and Numbers

Codeforces 449D:Jzzhu and Numbers

题目链接:http://codeforces.com/problemset/status?friends=on

题目大意:给出$n$个数,求有多少种组合使得$a_{i_1}\&a_{i_2}\&...\&a_{i_k}=0(0 \leqslant i < n)$,答案对$10^9+7$取模.

容斥原理+DP

设位与$(\&)$后二进制表示中有$k$个$1$的组合数为$A_k$,则有,

$A_0=$所有情况$-A_1+A_2-...+(-1)^kA_k=$所有情况$+\sum_{i=1}^k(-1)^kA_k$.

关键在于求出$A_k$.

我们曾在这道题(http://www.cnblogs.com/barrier/p/6664229.html)里求过:

$n$个数中,与$x$位与后仍为$x$的个数$f(x)$,

而若干个数位与后为$x$的组合数为$2^{f(x)}-1$.

至此,已能够求出$A_K$.

若设$g(x)$为$x$的二进制表示中$1$的个数,则$A_0=$所有情况$+\sum_{i=1}^k(-1)^{g(i)}(2^{f(i)}-1)$.

(由于任何数位与$0$均为$0$,所以有$f(0)=n$,故可以化简成$A_0=\sum_{i=0}^k(-1)^{g(i)}(2^{f(i)}-1)$)

对于这道题来说,可以预处理$2^k\%mod$,总复杂度为$O(nlgn)$.

(当然也可以不进行预处理,考虑到乘法溢出,复杂度为$O(nlg^3n)$,也是可以过的...)

代码如下:

 1 #include <cstdio>
 2 #define N 1000005
 3 using namespace std;
 4 typedef long long ll;
 5 const int mod=1e9+7;
 6 int n,t,f[1<<20],pow2[1<<20];
 7 int mus(int x,int y){
 8     return (x-y+mod)%mod;
 9 }
10 void getf(){
11     for(int i=0;i<20;++i)
12         for(int j=0;j<(1<<20);++j)
13             if((j&(1<<i))==0)f[j]+=f[j|(1<<i)];
14 }
15 int solve(){
16     getf();
17     int ans=mus(pow2[n],1);
18     for(int i=1;i<(1<<20);++i){
19         int g=0;
20         for(int j=0;j<20;++j)if(i&(1<<j))g++;
21         if(g&1)ans=mus(ans,mus(pow2[f[i]],1));
22         else ans=(ans+mus(pow2[f[i]],1))%mod;
23     }
24     return ans;
25 }
26 int main(void){
27     scanf("%d",&n);
28     for(int i=0;i<n;++i){
29         scanf("%d",&t);
30         f[t]++;
31     }
32     pow2[0]=1;
33     for(int i=1;i<=1000000;++i)pow2[i]=(2*pow2[i-1])%mod;
34     printf("%d\n",solve());
35 }
时间: 2024-08-05 06:24:42

Codeforces 449D:Jzzhu and Numbers的相关文章

Codeforces 449D:Jzzhu and Numbers(高维前缀和)

[题目链接] http://codeforces.com/problemset/problem/449/D [题目大意] 给出一些数字,问其选出一些数字作or为0的方案数有多少 [题解] 题目等价于给出一些集合,问其交集为空集的方案数, 我们先求交集为S的方案数,记为dp[S],发现处理起来还是比较麻烦, 我们放缩一下条件,求出交集包含S的方案数,记为dp[S], 我们发现dp[S],是以其为子集的方案的高维前缀和, 我们逆序求高维前缀和即可,之后考虑容斥,求出交集为0的情况, 我们发现这个容斥

Codeforces 450E:Jzzhu and Apples(构造,数学)

E. Jzzhu and Apples time limit per test: 1 seconds memory limit per test: 256 megabytes input: standard input output: standard output Jzzhu has picked \(n\) apples from his big apple tree. All the apples are numbered from \(1\) to \(n\). Now he wants

Codeforces 450C:Jzzhu and Chocolate(贪心)

C. Jzzhu and Chocolate time limit per test: 1 seconds memory limit per test: 256 megabytes input: standard input output: standard output Jzzhu has a big rectangular chocolate bar that consists of \(n?×?m\) unit squares. He wants to cut this bar exact

Codeforces Round #257 (Div. 2) E题:Jzzhu and Apples 模拟

E. Jzzhu and Apples time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output Jzzhu has picked n apples from his big apple tree. All the apples are numbered from 1 to n. Now he wants to sell them to

Codeforces Round #257 (Div. 1) D - Jzzhu and Numbers 容斥原理 + SOS dp

D - Jzzhu and Numbers 这个容斥没想出来... 我好菜啊.. f[ S ] 表示若干个数 & 的值 & S == S得 方案数, 然后用这个去容斥. 求f[ S ] 需要用SOSdp #include<bits/stdc++.h> #define LL long long #define fi first #define se second #define mk make_pair #define PLL pair<LL, LL> #define

codeforces 449D DP+容斥

Jzzhu and Numbers Time Limit:2000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64u Submit Status Appoint description:  System Crawler  (2014-07-20) Description Jzzhu have n non-negative integers a1, a2, ..., an. We will call a sequence o

codeforces 446C DZY Loves Fibonacci Numbers(数学 or 数论+线段树)

In mathematical terms, the sequence Fn of Fibonacci numbers is defined by the recurrence relation F1 = 1; F2 = 1; Fn = Fn - 1 + Fn - 2 (n > 2). DZY loves Fibonacci numbers very much. Today DZY gives you an array consisting of n integers: a1, a2, ...,

codeforces 446C DZY Loves Fibonacci Numbers 数论+线段树成段更新

DZY Loves Fibonacci Numbers Time Limit:4000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64u Submit Status Appoint description:  System Crawler  (2014-07-14) Description In mathematical terms, the sequence Fn of Fibonacci numbers is defi

Codeforces Round #257 (Div. 1) (Codeforces 449D)

思路:定义f(x)为 Ai & x==x  的个数,g(x)为x表示为二进制时1的个数,最后答案为    .为什么会等于这个呢:运用容斥的思想,如果 我们假设 ai&x==x 有f(x)个,那么 这f(x)个 组成集合的子集 & 出来是 >=x那么我们要扣掉>x的 ...  因为这里我们要求的是 & 之后等于0 一开始1个数为0那么就是 1个数为偶数时加上去,  为奇数时减掉了. 那么就剩下求f(x)    .我们把A[i]和x的二进制 分成  前 (20-k)