【数位DP】 HDU 3693 Math teacher's homework
通道: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: