题意:给你三个数A,B,C 现在要你找到满足 A and B >C 或者 A 异或 B < C 的对数。
思路:我们可以走对立面 把既满足 A and B <= C 也满足 A 异或 B >= C的个数用数位dp统计出来 最后用A*B减去即可
#include <bits/stdc++.h> using namespace std; const double pi = acos(-1.0); const int N = 1e6+7; const int inf = 0x3f3f3f3f; const double eps = 1e-6; typedef long long ll; const ll mod = 1e7+9; int bita[50],bitb[50],bitc[50]; ll dp[50][2][2][2][2]; ll dfs(int len,int maxa,int maxb,int ad,int xo){ if(!len) return 1; if(dp[len][maxa][maxb][ad][xo]>=0) return dp[len][maxa][maxb][ad][xo]; ll res=0; int upa=maxa?bita[len]:1; int upb=maxb?bitb[len]:1; for(int i=0;i<=upa;i++) for(int j=0;j<=upb;j++){ if((ad&&(i&j)>bitc[len])||xo&&(i^j)<bitc[len]) continue; res+=dfs(len-1,maxa&&(i==upa),maxb&&(j==upb), ad&&((i&j)==bitc[len]),xo&&((i^j)==bitc[len])); } dp[len][maxa][maxb][ad][xo]=res; return res; } ll solve(ll A,ll B,ll C){ int lena,lenb,lenc; lena=lenb=lenc=0; while(A){bita[++lena]=A&1; A>>=1;} while(B){bitb[++lenb]=B&1; B>>=1;} while(C){bitc[++lenc]=C&1; C>>=1;} int len=max(lena,max(lenb,lenc)); return dfs(len,1,1,1,1); } int main(){ ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); int t; cin>>t; while(t--){ memset(dp,-1,sizeof(dp)); memset(bita,0,sizeof(bita)); memset(bitb,0,sizeof(bitb)); memset(bitc,0,sizeof(bitc)); ll A,B,C; cin>>A>>B>>C; ll ans=solve(A,B,C); ans-=max(0LL,A-C+1); ans-=max(0LL,B-C+1); cout<<A*B-ans<<endl; } }