题目链接:CF1245 F.Daniel and Spring Cleaning
题意:给你一个区间,问区间内有多少对数满足a^b==a+b;([a,b]和[b,a]是两个答案)
分析:由题意知道是求a&b==0的对数,既然是位运算就可以转化成二进制下的数位DP,1e9不到30位;
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int s1[35],s2[35];
ll dp[35][2][2];
ll dfs(int pos,bool lim1,bool lim2)//是否要取上界
{
if(pos==0) return 1;
if(~dp[pos][lim1][lim2]) return dp[pos][lim1][lim2];
int mx1,mx2;mx1=mx2=1;
if(lim1) mx1=s1[pos];
if(lim2) mx2=s2[pos];
ll res=0;
for(int i=0;i<=mx1;i++) for(int j=0;j<=mx2;j++)
if((i&j)==0) res+=dfs(pos-1,lim1&&i==mx1,lim2&&j==mx2);
return dp[pos][lim1][lim2]=res;
}
ll cal(ll a,ll b)
{
if(a<0 || b<0) return 0;
memset(dp,-1,sizeof(dp));
for(int i=1;i<32;i++) s1[i]=a&1,a>>=1,s2[i]=b&1,b>>=1;
return dfs(31,1,1);
}
ll rua()
{
ll a,b;scanf("%lld%lld",&a,&b);
return cal(b,b)-2*cal(a-1,b)+cal(a-1,a-1);
}
int main()
{
int t;scanf("%d",&t);
while(t--) printf("%lld\n",rua());
return 0;
}