题目链接:
http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1406
这道题是1407 与与与与中的一个步骤
题意:给n个数,问在这n个数中与某个数 x 相与之后还是 x 的个数?
用 dp[x] 表示 x 这个数&上其他数还是 i 的个数
首先,自己跟自己相&,那肯定还是等于自己的,所以先把自己的个数加上
然后再考虑每个数的贡献,比如 1101,他跟 0101相&就还是 0101,所以直接把 1101的个数加到 0101上面,然后他跟 1001相&还是 1001,就把他的个数加到1001上面,依次这样~
但是我没有懂他们说的什么去重,我不管内层循环还是外层循环正起倒起跑都能AC,没懂没懂T_T
然后这道题还有一个收获就是用 puts("") 来输出换行,哇效率真高~
#include"bits/stdc++.h"
using namespace std;
const int maxn=1e6+5;
typedef long long LL;
int dp[maxn];
int Scan() { //????
int res = 0, flag = 0;
char ch;
if((ch = getchar()) == '-') flag = 1;
else if(ch >= '0' && ch <= '9') res = ch - '0';
while((ch = getchar()) >= '0' && ch <= '9')
res = res * 10 + (ch - '0');
return flag ? -res : res;
}
void Out(int a) { //????
if(a < 0) { putchar('-'); a = -a; }
if(a >= 10) Out(a / 10);
putchar(a % 10 + '0');
}
int main()
{
int N;
while(cin>>N)
{
memset(dp,0,sizeof dp);
for(int i=1;i<=N;i++)
{
int t;
t=Scan();
dp[t]++;//他自己与自己相与肯定还是自己三~
}
for(int k=0;k<20;k++)
{
for(int i=0;i<=maxn-5;i++)
{
if(i&(1<<k))dp[i^(1<<k)]+=dp[i];//计算i这个数对哪些数有贡献,就把他加在那个数上
}
}
for(int i=0;i<=1000000;i++)
{
Out(dp[i]);
puts("");//用这个来输出换行
}
}
}