51nod 1406 位运算/dp

Posted zzq

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了51nod 1406 位运算/dp相关的知识,希望对你有一定的参考价值。

http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1406

1406 与查询技术分享

题目来源: CodeForces
基准时间限制:2 秒 空间限制:131072 KB 分值: 80 难度:5级算法题
技术分享 收藏
技术分享 关注

有n个整数。输出他之中和x相与之后结果为x的有多少个。x从0到1,000,000

Input
第一行输入一个整数n。(1<=n<=1,000,000).
第二行有n个整数a[0],a[1],a[2],...a[n-1],以空格分开.(0<=a[i]<=1,000,000)
Output
对于每一组数据,输出1000001行,第i行对应和i相与结果是i的有多少个数字。
Input示例
3
2 3 3
Output示例
3
2
3
2
0
0
……
后面还有很多0

枚举每个数的子集然后更新,但是...会出现重复更新的情况,例如 1101->(1100,1001,101), 这些数有些子集重复导致WA。
其实只要把两次循环交换一下就避免了这种情况!
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define LL long long
 4 #define inf 0x3f3f3f3f
 5 LL mod=1e9+7;
 6 int dp[1000005];
 7 inline int read()
 8 {
 9     char c;      while(!isdigit(c=getchar()));
10     int r=c-0; while(isdigit(c=getchar())) {r=(r<<3)+(r<<1)+c-0;}
11     return r;
12 }
13 char _n=\n;
14 inline void write(int x)
15 {
16     int a1=0,a[20];
17     a[1]=0;
18     if (!x) a1++;
19     while (x)
20     {
21         a[++a1]=x%10;x/=10;
22     }
23     for (int i=a1;i>=1;i--)
24         putchar(a[i]+0);
25     putchar(_n);
26 }
27 int main()
28 {
29     int N,i,j,k,ai;
30     scanf("%d",&N);
31     for(i=1;i<=N;++i){
32         dp[read()]++;
33     }
34     for(j=20;j>=0;--j){
35     for(i=1;i<=1000000;++i)
36     {
37             if(i&(1<<j)) dp[i^(1<<j)]+=dp[i];
38     }
39     }
40     cout<<N<<endl;
41     for(i=1;i<=1000000;++i) {write(dp[i]);}
42     return 0;
43 }

 




以上是关于51nod 1406 位运算/dp的主要内容,如果未能解决你的问题,请参考以下文章

51nod 1406 与查询 dp 考虑每一位 避免重复

51nod 1406:与查询

51Nod 1684 子集价值 (平方和去括号技巧)

位运算 异或51nod区间xor

51nod.3047位移运算(位运算)

51nod.3047位移运算(位运算)