I - Wall Painting (二进制,组合数学)

Ms.Fang loves painting very much. She paints GFW(Great Funny Wall) every day. Every day before painting, she produces a wonderful color of pigments by mixing water and some bags of pigments. On the K-th day, she will select K specific bags of pigments and mix them to get a color of pigments which she will use that day. When she mixes a bag of pigments with color A and a bag of pigments with color B, she will get pigments with color A xor B.
When she mixes two bags of pigments with the same color, she will get color zero for some strange reasons. Now, her husband Mr.Fang has no idea about which K bags of pigments Ms.Fang will select on the K-th day. He wonders the sum of the colors Ms.Fang will get with different plans.

For example, assume n = 3, K = 2 and three bags of pigments with color 2, 1, 2. She can get color 3, 3, 0 with 3 different plans. In this instance, the answer Mr.Fang wants to get on the second day is 3 + 3 + 0 = 6.
Mr.Fang is so busy that he doesn’t want to spend too much time on it. Can you help him?
You should tell Mr.Fang the answer from the first day to the n-th day.
Input
There are several test cases, please process till EOF.
For each test case, the first line contains a single integer N(1 <= N <= 10 3).The second line contains N integers. The i-th integer represents the color of the pigments in the i-th bag.
Output
For each test case, output N integers in a line representing the answers(mod 10 6 +3) from the first day to the n-th day.
Sample Input
4
1 2 10 1
Sample Output
14 36 30 8
这个题有毒的

这道题的大意就是有N袋颜料,他们的颜色分别为K1,K2,.....,Kn,n袋颜料之间,混合得到的颜色为color = K1K2.....^Kn,Mr.Fang想知道在第i天用i袋颜料混合得到的颜色是什么。答案要求你输出从第1天到第n天,每天获得的所有的可能颜色的编号和为多少。
比如我们分析一下样例
input
n
n1 n2 n3 n4
output
ans1 ans2 ans3 ans4

ans1 = n1 + n2 + n3 + n4
ans2 = n1^n2 + n1^n3 + n1^n4 + n2^n3 + n2^n4 + n3^n4
ans3 = n1n2n3 + n1n2n4 + n2n3n4 + n1n3n4
ans4 = n1n2n3^n4
现在还看不出有啥规律是吧
那现在我们把这些数字换成二进制
input
4
0001 0010 1010 0001

ans = 0001 + 0010 + 1010 + 0001 = 1022
ans2 = 0001^0010 + 0001^1010 + 0001^0001 + 0010^1010 + 0010^0001 + 1010^0001
因为 1^1 = 0,1^0 = 1;
所以 当 每一位上的1的个数为偶数的时候的这种组合是没有贡献的
把样例中的数据的每一位上的 1 加起来
3 2 1 0 (位)
1 0 2 2
把数字之间的组合 转换为 每一个位上的数字之间的组合
每一位都是独立的

比如在0这个位上1的数目为2 , 0为2
1 1 0 0
组合有六种 C42 = 6
但是其中 1^ 1和1^0这两种组合是无效的,所以这一位上的组合的数目是 4
同理可计算得
3 2 1 0 (位)
3 0 4 4
所以结果就是把最后的每一位上的数转换出来ans1 = 3pow(2,3) + 0pow(2,2)+ 4pow(2,1) + 4pow(2,0) = 36

当然我们可以把这个过程转换为公式
ans[i] += ((c[ A[j] ][k] * c[ n-A[j] ][i-k] ) * (1< 我们需要选取i个颜色混合的结果;
c[ A[j] ][k] 为在A[j] 个1 中选取k个1;
k是1的个数 ,k为奇数,因为1^1是没有贡献的。
c[ n - A[j] ][ i-k ]为在n-A[j]个0中选取i-k个0;
他们的乘积就是每一位上可能的组合的数目,然后再乘这一位上的值(*2^bitpos)就是这一位上的结果,然后把每一位上的加起来就行了。

#include
#include
#include
#include
#include
using namespace std;

#define maxn (1055)
#define LL long long 
const int mod = 1e6+3;

int n;
LL A[50],ans[maxn];
LL c[maxn][maxn];

void init()
{
     c[0][0] = 1;
    for(int i=1;i<=maxn;i++)
    {
        c[i][0] = 1;
        for(int j=1;j

你可能感兴趣的:(I - Wall Painting (二进制,组合数学))