【数位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:

posted @ 2014-11-01 10:11  mithrilhan  阅读(342)  评论(0编辑  收藏  举报