B 计算几何(数位dp)

Posted CCSU_Cola

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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);
    }
}

以上是关于B 计算几何(数位dp)的主要内容,如果未能解决你的问题,请参考以下文章

2016 CCPC 网络赛 B 高斯消元 C 树形dp(待补) G 状压dp+容斥(待补) H 计算几何

Code Chef MINPOLY(计算几何+dp)

hdu3734(数位dp)

hdu4389 Xmod f(x) 数位DP

HDU 3652 B-number(数位dp)

P2022 有趣的数(二分&数位dp)