题目链接
题目思路
首先(log(i+j))只和(i+j)化为二进制的最高位有关
并且(i&j=0) 所以不会有进位,那么就是和(i,j)中的二进制最高位的最高位有关
然后就是数位(dp)
设的是(dp[pos][p][lim1][lim2])
第(pos)的位置最高位位(p),以及(i,j)是否有限制了 但是这样会(tle)
要把(p)改为是否当前为1,并且以前没有1出现过
说是套路数位(dp),但是我不会啊...
代码
#include<bits/stdc++.h>
#define fi first
#define se second
#define debug cout<<"I AM HERE"<<endl;
using namespace std;
typedef long long ll;
const int maxn=2e5+5,inf=0x3f3f3f3f,mod=1e9+7;
const double eps=1e-6;
int x,y;
int a[40],b[40];
ll dp[32][2][2][2];
ll ans;
ll dfs(int pos,int flag,int lim1,int lim2){
if(pos==-1){
return 1;
}
if(dp[pos][flag][lim1][lim2]!=-1){
return dp[pos][flag][lim1][lim2];
}
int up1=(lim1?a[pos]:1);
int up2=(lim2?b[pos]:1);
ll num=0;
for(int i=0;i<=up1;i++){
for(int j=0;j<=up2;j++){
if(i&j) continue;
ll tmp=dfs(pos-1,flag||i||j,lim1&&i==a[pos],lim2&&j==b[pos]);
if(!flag&&(i||j)){
ans+=1ll*(pos+1)*tmp%mod;
ans%=mod;
}
num+=tmp;
num%=mod;
}
}
return dp[pos][flag][lim1][lim2]=num;
}
void solve(int x,int y){
ans=0;
memset(dp,-1,sizeof(dp));
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
for(int i=0;i<=30;i++){
if((x>>i)&1) a[i]=1;
if((y>>i)&1) b[i]=1;
}
dfs(30,0,1,1);
printf("%lld
",ans);
}
signed main(){
int _;scanf("%d",&_);
while(_--){
scanf("%d%d",&x,&y);
solve(x,y);
}
return 0;
}