HDU 6869:Xor(数位dp)

在这里插入图片描述


这题与 Comet OJ - Contest #12 :D.XOR Pair 的做法基本相同。

对于 x ⨁ y ≤ w x \bigoplus y \leq w xyw 可以转化为 w − x ⨁ y ≥ 0 w - x \bigoplus y \geq 0 wxy0,用相同的处理方法,将贡献诸位递推即可,但这题有2000组样例,如果不对达到上界的状态记忆化的话,最差复杂度会达到 O ( 2000 ∗ 900 ∗ 2 ∗ 2 ∗ 3 ∗ 3 ∗ 3 ) O(2000 * 900 * 2 * 2 * 3 * 3 * 3) O(200090022333)


代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int t;
ll a, b, k, w;
ll dp[33][3][3][3][2][2];
ll dfs(int pos,int v1,int v2,int v3,int lx,int ly) {
    
    
	v1 = min(v1,1); v2 = min(v2,1); v3 = min(v3,1);
	if (v1 < -1 || v2 < -1 || v3 < 0) return 0;
	if (pos < 0) return v1 >= 0 && v2 >= 0 && v3 >= 0;
	if (dp[pos][v1 + 1][v2 + 1][v3 + 1][lx][ly] != -1) return dp[pos][v1 + 1][v2 + 1][v3 + 1][lx][ly];
	int upx = (lx == 1 ? (a >> pos & 1) : 1);
	int upy = (ly == 1 ? (b >> pos & 1) : 1);
	int t = (k >> pos & 1);
	int p = (w >> pos & 1);
	ll ans = 0;
	for (int x = 0; x <= upx; x++)
		for (int y = 0; y <= upy; y++)
			ans += dfs(pos - 1,v1 * 2 + t + x - y,v2 * 2 + t + y - x,v3 * 2 + p - (x ^ y),lx && x == upx,ly && y == upy);
	return dp[pos][v1 + 1][v2 + 1][v3 + 1][lx][ly] = ans;
}
int main() {
    
    
	scanf("%d",&t);
	while (t--) {
    
    
		scanf("%lld%lld%lld%lld",&a,&b,&k,&w);
		memset(dp,-1,sizeof dp);
		printf("%lld\n",dfs(30,0,0,0,1,1));
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41997978/article/details/108831275