Daniel and Spring Cleaning
题解
很容易发现,原式等价于。
再差分一下,。
令,接下来,来考虑一下函数该怎么求。
由于是二进制,很容易想到数位dp,令为在转化为二进制后,的第位为,的第位为时的满足条件的方案数。
dp的转换也十分好想,判断是否达到上界即可。
源码
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int,int> pii;
int t,l,r;LL dp[40][2][2];
LL calc(LL a,LL b){
if(a<0||b<0)return 0;
memset(dp,0,sizeof(dp));dp[32][1][1]=1;
for(int i=31;i>=0;i--)
for(int j=0;j<2;j++)
for(int k=0;k<2;k++){
bool nxtj=(j&&!((a>>i)&1LL)),nxtk=(k&&!((b>>i)&1LL));
dp[i][nxtj][nxtk]+=dp[i+1][j][k];
if(((a>>i)&1)||!j)dp[i][j][nxtk]+=dp[i+1][j][k];
if(((b>>i)&1)||!k)dp[i][nxtj][k]+=dp[i+1][j][k];
}
return dp[0][0][0]+dp[0][1][0]+dp[0][0][1]+dp[0][1][1];
}
signed main(){
scanf("%d",&t);
while(t--){
scanf("%d %d",&l,&r);l--;
printf("%lld\n",calc(r,r)-calc(l,r)*2ll+calc(l,l));
}
return 0;
}