题意:给定A、B、C,问1<=x<=A,1<=y<=B,有多少对(x,y)满足x&y>c或x^y<c。
思路:考虑约束条件的反面,计算满足x&y<=c并且x^y>=c的对数,数位dp。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int a[40],b[40],c[40];
ll dp[32][2][2][2][2][2][2];
ll dfs(int pos,bool limit1,bool limit2,bool f1,bool f2,bool z1,bool z2){
if(pos==0){return z1&&z2;}
if(dp[pos][limit1][limit2][f1][f2][z1][z2]!=-1)return dp[pos][limit1][limit2][f1][f2][z1][z2];
int ed1=limit1?a[pos]:1;
int ed2=limit2?b[pos]:1;
ll ans=0;
for(int i=0;i<=ed1;i++){
for(int j=0;j<=ed2;j++){
if(!f1)if((i&j)>c[pos])continue;
if(!f2)if((i^j)<c[pos])continue;
bool tf1=f1||((i&j)<c[pos]);
bool tf2=f2||((i^j)>c[pos]);
ans+=dfs(pos-1,limit1&&(i==ed1),limit2&&(j==ed2),tf1,tf2,z1||(i==1),z2||(j==1));
}
}
dp[pos][limit1][limit2][f1][f2][z1][z2]=ans;
return ans;
}
int main()
{
int t;
scanf("%d",&t);
while(t--){
int A,B,C;
scanf("%d%d%d",&A,&B,&C);
int cnt;
memset(a,0,sizeof a);
memset(b,0,sizeof a);
memset(c,0,sizeof c);
memset(dp,-1,sizeof dp);
ll ans=1ll*A*B;
cnt=0;
while(A){
a[++cnt]=A&1;
A>>=1;
}
cnt=0;
while(B){
b[++cnt]=B&1;
B>>=1;
}
cnt=0;
while(C){
c[++cnt]=C&1;
C>>=1;
}
printf("%lld\n",ans-dfs(30,1,1,0,0,0,0));
}
return 0;
}