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)的主要内容,如果未能解决你的问题,请参考以下文章