B 计算几何(数位dp)

问题链接

由于小 L 追女孩子的时间不多了,于是这里只有简单版题意。

共有 T 组询问,每次给定 l,r,你需要求出在 [l,r] 中有多少个数在二进制下 1 的个数有奇数个。

例如 4=(100)2,在二进制下有 1 个 1 ,那么如果 l=r=4 ,答案为 1 。

例如 5=(101)2​ ,在二进制下有 2 个 1 ,那么如果 l=r=5 ,答案为 0 。

思路:将每个数用二进制分解,然后数位dp得到0到L-1的奇数个1的数的个数,以及0到R的奇数个1的数的个数。做减法输出即可。

代码

#include<bits/stdc++.h>
using namespace std;
#define ll long long
int p[200];
ll dp[110][110][3];
ll dfs(int pos,int sum,int lim){
    if(pos==0){
        if(sum&1)return 1;
        else return 0;
    }
    if(dp[pos][sum][lim]!=-1)return dp[pos][sum][lim];
    int up=lim?p[pos]:1;
    ll ans=0;
    for(int i=0;i<=up;i++){
        if(i==1)ans+=dfs(pos-1,sum+1,lim&&(i==up));
        else ans+=dfs(pos-1,sum,lim&&(i==up));
    }
    return dp[pos][sum][lim]=ans;
}
ll solve(ll a){
    if(a==0)return 0;
     int idx=0;
     while(a){
         if(a&1)p[++idx]=1;
         else p[++idx]=0;
         a=a/2;
     }
     memset(dp,-1,sizeof dp);
     return dfs(idx,0,1);
}
int main(){
    int t;
    scanf("%d",&t);
    while(t--){
        ll l,r;
        scanf("%lld%lld",&l,&r);
        ll f=solve(l-1);
        ll ff=solve(r);
        printf("%lld\n",ff-f);
    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值