2019 cattle off more school seventh H Pair digit DP

That Italy: 3 to give you a number of A, B, C asked how many of the pair (i, j), 1 <= i <= A, 1 <= j <= B, i AND j> C or i XOR j <C. A, B, C range 1e9.

Ideas: a look that is pushing the field equations plus what to do screen, to no avail. After know that this is a digital DP (orz from the following lines of code seniors). First of all, we can put the problem and minimize i AND j <C and i XOR j> C number of the number, this number by subtracting the total number (A * B). We set several process variables DP: ok1, i and j bits previously filled have been met i AND j <C, ok2 empathy. lim1 indicates whether i can easily fill, lim2 empathy. zero1 bit indicates whether the fill above all 0, zero2 empathy. dp when the memory of the search on the line. DP very intuitive process is not explained. (I wrote so think on most position DP arena, too dishes QAQ)

Code:

#include <bits/stdc++.h>
#define LL long long
using namespace std;
const int maxn = 55;
int a[maxn], b[maxn], c[maxn];
LL dp[maxn][2][2][2][2][2][2];
LL dfs(int dep, bool ok1, bool ok2, bool lim1, bool lim2, bool zero1, bool zero2) {
	if(dep == -1) {
		return (zero1 == 0 && zero2 == 0);
	}
	if(dp[dep][ok1][ok2][lim1][lim2][zero1][zero2] != -1) {
		return dp[dep][ok1][ok2][lim1][lim2][zero1][zero2];
	}
	int mx1, mx2;
	if(lim1) mx1 = a[dep];
	else mx1 = 1;
	if(lim2) mx2 = b[dep];
	else mx2 = 1;
	LL ans = 0;
	for (int i = 0; i <= mx1; i++) {
		for (int j = 0; j <= mx2; j++) {
			if(!ok1 && ((i & j) > c[dep])) continue;
			if(!ok2 && ((i ^ j) < c[dep])) continue;
			ans += dfs(dep - 1, ok1 || ((i & j) < c[dep]), 
			ok2 || ((i ^ j) > c[dep]), lim1 && (i == mx1), 
			(lim2 && j == mx2), zero1 && (i == 0), zero2 && (j == 0));
		}
	}
	dp[dep][ok1][ok2][lim1][lim2][zero1][zero2] = ans;
	return ans;
}
LL solve(LL A, LL B, LL C) {
	LL res = A * B; 
	memset(a, 0, sizeof(a));
	memset(b, 0, sizeof(b));
	memset(c, 0, sizeof(c));
	memset(dp, -1, sizeof(dp));
	for (int i = 0; i <= 35; i++) {
		a[i] = A & 1; A >>= 1;
		b[i] = B & 1; B >>= 1;
		c[i] = C & 1; C >>= 1;
	}
	return res - dfs(35, 0, 0, 1, 1, 1, 1);
}
int main() {
	int T;
	LL A, B, C;
	scanf("%d", &T);
	while(T--) {
		scanf("%lld%lld%lld", &A, &B, &C);
		printf("%lld\n", solve(A, B, C));
	}
}

  

Guess you like

Origin www.cnblogs.com/pkgunboat/p/11324586.html