题目链接:点我啊╭(╯^╰)╮
题目大意:
解题思路:
考虑到高位决定结果,所以从高位开始数位dp
o
a
oa
oa 与
o
b
ob
ob 表示
a
a
a 和
b
b
b 是否到达了上界
o
a
n
d
oand
oand 与
o
x
o
r
oxor
oxor 表示高位的和与异或是否出现非零
z
a
za
za 与
z
b
zb
zb 限制正数
核心:两个数同时数位dp
#include<bits/stdc++.h>
#define rint register int
#define deb(x) cerr<<#x<<" = "<<(x)<<'\n';
using namespace std;
typedef long long ll;
typedef pair <int,int> pii;
const ll mod = 998244353;
const int maxn = 2e6 + 10;
int T, A, B, C;
int a[40], b[40], c[40];
ll dp[40][2][2][3][3][2][2];
ll dfs(int wz, int oa, int ob, int oand, int oxor, int za, int zb){
ll& ret = dp[wz][oa][ob][oand+1][oxor+1][za][zb];
if(ret != -1) return ret;
if(wz == 0){
if((oand>0 || oxor<0) && za && zb) return ret = 1;
return ret = 0;
}
wz--, ret = 0;
for(int i=0; i<=(oa?1:a[wz]); i++)
for(int j=0; j<=(ob?1:b[wz]); j++)
ret += dfs(wz, oa|(i^a[wz]), ob|(j^b[wz]), oand?oand:(i&j)-c[wz],\
oxor?oxor:(i^j)-c[wz], za|i, zb|j);
return ret;
}
int main() {
scanf("%d", &T);
while(T--){
scanf("%d%d%d", &A, &B, &C);
memset(dp, -1, sizeof(dp));
for(int i=30; ~i; i--){
a[i] = (A >> i) & 1;
b[i] = (B >> i) & 1;
c[i] = (C >> i) & 1;
}
printf("%lld\n", dfs(31,0,0,0,0,0,0));
}
}