Meaning of the questions:
Portal
you \ (A, B, C \) , the requirements on how much you give \ ((x, y) \ ) satisfies \ (x \ in [1, A], y \ in [1, B] \) , and any of the following conditions are met: \ (X \ Y &> C \) or \ (X \ Y Oplus <C \) .
Ideas:
Digital \ (DP \) , done before digital \ (DP \) is just a number and relevant, and today is the number two related, a little magical. Here I opened a nine-dimensional, the \ (i \) bit \ (x \) is \ (J \) , \ (the y-\) is \ (k \) , to \ (the first \) case, \ (second \) case, \ (the X-\) to reach the upper bound, \ (the y-\) to reach the upper bound, \ (the X-\) leading zeros, \ (the y-\) leading zeros. Initially opened only five dimensions, but \ (T \) a. Because in binary, where a number of cases reach the upper bound is actually very much, so if I always requires \ (! Limita \ \ & \ & \! Limitb \) to return when \ (dp \) it is bound to cause a lot of the case should \ (dfs \) to solve many times. Leading zero empathy.
Code:
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<ctime>
#include<cmath>
#include<cstdio>
#include<string>
#include<vector>
#include<cstring>
#include<sstream>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = 100000 + 5;
const int INF = 0x3f3f3f3f;
const ull seed = 131;
const ll MOD = 1e9 + 7;
using namespace std;
ll dp[40][3][3][3][3][3][3][3][3]; //第i位x是j,y是k,对第一种情况,对第二种情况,x到达上界,y到达上界,x前导零,y前导零
//0不知 1不满足 2满足
int bit1[40], bit2[40], C;
//x and y > C
//x xor y < C
ll dfs(int pos, int x, int y, int oxor, int oand, int stx, int sta, bool limita, bool limitb, bool leadx, bool leady){
if(pos == -1){
if((stx == 2 || sta == 2) && !leadx && !leady) return 1;
return 0;
}
if(dp[pos][x][y][stx][sta][limita][limitb][leadx][leady] != -1) return dp[pos][x][y][stx][sta][limita][limitb][leadx][leady];
int top1 = limita? bit1[pos] : 1;
int top2 = limitb? bit2[pos] : 1;
ll ret = 0;
for(int i = 0; i <= top1; i++){
for(int j = 0; j <= top2; j++){
int nxor = (oxor << 1) + (i ^ j), nand = (oand << 1) + (i & j);
int nstx = stx, nsta = sta;
if(stx == 0 && nxor > (C >> pos)){
nstx = 1;
}
else if(stx == 0 && nxor < (C >> pos)){
nstx = 2;
}
if(sta == 0 && nand > (C >> pos)){
nsta = 2;
}
else if(sta == 0 && nand < (C >> pos)){
nsta = 1;
};
ret += dfs(pos - 1, i, j, nxor, nand, nstx, nsta, limita && i == top1, limitb && j == top2, leadx && !i, leady && !j);
}
}
dp[pos][x][y][stx][sta][limita][limitb][leadx][leady] = ret;
return ret;
}
ll solve(int A, int B){
int pos = 0;
if(A < B) swap(A, B);
while(A){
bit1[pos] = A & 1;
A >>= 1;
bit2[pos++] = B & 1;
B >>= 1;
}
ll ans = dfs(pos - 1, 0, 0, 0, 0, 0, 0, true, true, true, true);
return ans;
}
int main(){
int T;
scanf("%d", &T);
while(T--){
memset(dp, -1, sizeof(dp));
int a, b;
scanf("%d%d%d", &a, &b, &C);
ll ans = solve(a, b);
printf("%lld\n", ans);
}
return 0;
}