有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
System Message
(题目提供者)
题解:
简单dp,设f[i]表示有多少个数与i与后为i。
f[i]=sigma(f[i-(1<<j)])(i&(1<<j))
ps:这题网上循环j都是倒着来的,但是我有些不懂,应该顺着来也是没有影响的。。估计是他们都看了某些人的题解而没有仔细思考吧。
ps2:此题不知道什么原因,用c++交会超时,用visual c++交却没问题。
代码:
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <stdio.h>
#include <cstring>
#include <vector>
#include <math.h>
#include <queue>
#include <set>
#include <map>
using namespace std;
int n,i,t,j,s,a[1000001];
int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int main(){
n=read();
for(i=1;i<=n;i++){
t=read();
a[t]++;
s=max(s,t);
}
s=min(s,1000001);
for(i=0;i<=20;i++)
for(j=1;j<=s;j++)
if(j&(1<<i))a[j-(1<<i)]+=a[j];
printf("%d\n",n);
for(i=1;i<=1000000;i++)printf("%d\n",a[i]);
}