CF1245 F.Daniel and Spring Cleaning【数位DP】

题目链接: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;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值