题目链接:

http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1406
这道题是1407 与与与与中的一个步骤
题意:给n个数,问在这n个数中与某个数 x 相与之后还是 x 的个数?
d p [ x ] dp[x] dp[x] 表示 x x x 这个数&上其他数还是 i i i 的个数

首先,自己跟自己相&,那肯定还是等于自己的,所以先把自己的个数加上

然后再考虑每个数的贡献,比如 1101 1101 1101,他跟 0101 0101 0101相&就还是 0101 0101 0101,所以直接把 1101 1101 1101的个数加到 0101 0101 0101上面,然后他跟 1001 1001 1001相&还是 1001 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("");//用这个来输出换行 
		}
	}
}