通道:http://acm.hdu.edu.cn/showproblem.php?pid=3693
题意:给出N个数,给定k,求x1,x2,x3,...,xn,(xi<=mi)的种数,使得x1^x2^x3...^xn=k
思路:考虑每一位所能贡献的结果。在该位dp[i][j]:前i个数中有j个1的方案数。
如果第i个数该位为1,那么dp[i][j] = dp[i - 1][j] * (num[i] - (2^d - 1))[该位填0]
还有dp[i][j] = dp[i - 1][j - 1] * (2^d)[该位填1]
如果第i个数该位为0,那么dp[i][j] = dp[i - 1][j] * (num[i] + 1)
tot-j个固定,j个可变,那么ans+=dp[n][j]
代码:
import java.io.*;
import java.util.*;
public class Main {
final static int MAX_N = 57;
final static long MOD = 1000000003;
long num[] = new long[MAX_N];
long dp[][] = new long[MAX_N][MAX_N];
void run() throws IOException {
while (true) {
int n = cin.nextInt();
int k = cin.nextInt();
if (0 == n && 0 == k) break;
for (int i = 1; i <= n; ++i)
num[i] = cin.nextLong();
long ans = 0; int t = 0;
for (t = 30; t >= 0; --t) {
for (int j = 0; j < MAX_N; ++j)
Arrays.fill(dp[j], 0);
long tot = 0, limit = 1 << t;
dp[0][0] = 1;
for (int i = 1; i <= n; ++i) {
if ((num[i] >> t & 1) == 1) {
++tot;
for (int j = 0; j < tot; ++j)
dp[i][j] = (dp[i - 1][j] * (num[i] - (limit - 1))) % MOD;
dp[i][1] = (dp[i][1] + dp[i - 1][0]) % MOD;
for (int j = 2; j <= tot; ++j)
dp[i][j] = (dp[i][j] + dp[i - 1][j - 1] * limit) % MOD;
num[i] -= limit;
} else {
for (int j = 0; j <= tot; ++j)
dp[i][j] = (dp[i - 1][j] * (num[i] + 1)) % MOD;
}
}
int One = k >> t & 1;
for (int j = 1; j <= tot; ++j)
if (((tot - j) & 1) == One)
ans = (ans + dp[n][j]) % MOD;
if (One != (tot & 1)) break;
}
if (t == -1) ans =( ans + 1) % MOD;
out.println(ans);
}
out.close();
}
public static void main(String[] args) throws IOException {
new Main().run();
}
Main() {
cin = new InputReader(System.in);
// cin = new Scanner(System.in);
out = new PrintWriter(System.out);
}
PrintWriter out;
InputReader cin;
//Scanner cin;
class InputReader {
InputReader(InputStream in) {
reader = new BufferedReader(new InputStreamReader(in));
// try {
// reader = new BufferedReader(new FileReader("input.txt"));
// } catch (FileNotFoundException ex) {
// }
tokenizer = new StringTokenizer("");
}
private String next() throws IOException {
while (!tokenizer.hasMoreTokens()) {
tokenizer = new StringTokenizer(reader.readLine());
}
return tokenizer.nextToken();
}
public Integer nextInt() throws IOException {
return Integer.parseInt(next());
}
public Long nextLong() throws IOException {
return Long.parseLong(next());
}
private BufferedReader reader;
private StringTokenizer tokenizer;
}
}
TAG: