这题与 Comet OJ - Contest #12 :D.XOR Pair 的做法基本相同。
对于 x ⨁ y ≤ w x \bigoplus y \leq w x⨁y≤w 可以转化为 w − x ⨁ y ≥ 0 w - x \bigoplus y \geq 0 w−x⨁y≥0,用相同的处理方法,将贡献诸位递推即可,但这题有2000组样例,如果不对达到上界的状态记忆化的话,最差复杂度会达到 O ( 2000 ∗ 900 ∗ 2 ∗ 2 ∗ 3 ∗ 3 ∗ 3 ) O(2000 * 900 * 2 * 2 * 3 * 3 * 3) O(2000∗900∗2∗2∗3∗3∗3)。
代码:
#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;
}