HDU 4810 Wall Painting (exclusive or + ), hdu4810
No. estimate the time complexity. For C (n, m), it will be blind to the scale of 500. At that time, I thought the algorithm should be close to the constant level.
If it is true, it is inevitable to kneel down. I looked back at the problem-solving report.
In other words, the competition is very fond of exception or, "bit" thinking, and combination problems.
When k numbers are selected for calculation, the possible occurrence of each bit is calculated separately, and the sum of all BITs is calculated. Even if a number can consist of multiple digits, a single digit is calculated at a time.
Record the number of 1 in each digit (only 32 bits are required here). For the day I, You must select an odd number of 1 to make this bitwise OR result 1, otherwise, it is 0. Let's take a look at the example,
4
1 2 10 1
The binary representation of these four numbers is:
0001
0010
1010
0001
For example, in the first day, select two from four to make an exception or. In the second place, there is only one and one, therefore, there are three ways to make this XOR or the result is 1 (that is, C (3rd) * C (), and the-bit value does not have 1, therefore, the variance or result must be 0, and there are 2 more than 1 in the 2nd bits. Therefore, there are 4 options. Similarly, there are also 4 options in the first place.
Therefore, the result is (1 <3) * C () + 0 * C () + (1 <1) * C) + (1 <0) * C (2, 1) * C (2, 1)
Note: 1. pre-process the C array. Note that in the range, the Type Selection on a single digit is an odd number but cannot exceed the optional number. It is especially prone to overflow. Use long
#include <iostream>#include <cstring>#include <cstdio>#include <algorithm>#define inf 0x3f3f3f3f#define maxn 1100#define MOD 1000003using namespace std;int N;long long rem[32],c[maxn][maxn];void init() { c[0][0] = c[1][0] = c[1][1] = 1; for (int i = 2; i < maxn; i++) { c[i][0] = 1; for (int j = 1; j <= i; j++) c[i][j] = (c[i-1][j] + c[i-1][j-1]) % MOD; } return ;}int main(){init(); while(~scanf("%d",&N)){ memset(rem,0,sizeof(rem)); for(int i=0;i<N;i++){ int k;scanf("%d",&k); for(int j=0;j<32;j++) if( (1<<j)& k ) rem[j]++; } for(int i=1;i<=N;i++){ long long ans=0; for(int j=0;j<32;j++){ for(int k=1;k<=rem[j] && k<=i;k+=2) ans=(ans+ ( c[N-rem[j]][i-k]* (c[rem[j]][k]* ( (1<<j)%MOD) )%MOD)%MOD)%MOD; } if(i==N) printf("%I64d\n",ans); else printf("%I64d ",ans); } }return 0;}