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
/* 51 nod 1406 与查询 problem: 有n个整数。输出他之中和x相与之后结果为x的有多少个。x从0到1000000 solve: 如果x与a[i]相与之后为x,那么x必定是a[i]二进制中1的组合. 所以就成了快速求x中1的所有组合. 最开始是枚举x,然后从高位到低位枚举. cnt[i - (1 << j)] += cnt[i]; 但是有的时候会出现重复,比如: 1011. 循环置换一下就好了 hhh-2016/09/09-16:19:21 */ #pragma comment(linker,"/STACK:124000000,124000000") #include <algorithm> #include <iostream> #include <cstdlib> #include <stdio.h> #include <cstring> #include <vector> #include <math.h> #include <queue> #include <set> #include <map> #define lson i<<1 #define rson i<<1|1 #define ll long long #define clr(a,b) memset(a,b,sizeof(a)) #define scanfi(a) scanf("%d",&a) #define scanfs(a) scanf("%s",a) #define scanfl(a) scanf("%I64d",&a) #define scanfd(a) scanf("%lf",&a) #define key_val ch[ch[root][1]][0] #define eps 1e-7 #define inf 0x3f3f3f3f3f3f3f3f using namespace std; const ll mod = 1000000007; const int maxn = 1001000; const double PI = acos(-1.0); const int limit = 33; template<class T> void read(T&num) { char CH; bool F=false; for(CH=getchar(); CH<'0'||CH>'9'; F= CH=='-',CH=getchar()); for(num=0; CH>='0'&&CH<='9'; num=num*10+CH-'0',CH=getchar()); F && (num=-num); } int stk[70], tp; template<class T> inline void print(T p) { if(!p) { puts("0"); return; } while(p) stk[++ tp] = p%10, p/=10; while(tp) putchar(stk[tp--] + '0'); putchar(' '); } int cnt[maxn]; int main() { int n,Max,x; clr(cnt,0); read(n); Max = 0; for(int i = 1; i <=n; i++) { read(x),Max = max(x,Max); cnt[x] ++ ; } int begi = min(1000001,Max); // cnt[0] = n; for(int j = 20; j >= 0 ; j --) { for(int i = 1; i <= begi; i++) { if(i & (1 << j)) { cnt[i - (1 << j)] += cnt[i]; } } } cnt[0] = n; for(int i = 0;i <= 1000000;i ++) print(cnt[i]); // for(int i = 0; i <= 10; i ++) // print(cnt[i]); return 0; }