0和1的熟练
想不出来了,遂打表。
受到了luobotianle的启发,就依据其建议学上了分块打表。
如0与1的熟练
问 L 到 R 之间,在二进制表示下(无前导0),0 的个数比 1 的个数多的数的个数。
那么我们就可以以 5e5 为块长来打表。
打表程序
#define yhl 0
#include<bits/stdc++.h>
using namespace std;
const int N=32,p=5e5;
bitset<N>bit;
int l,r,ans,ansl=0,cntl=0;
int main(){
freopen("biao.out","w",stdout);
for(register int i=1;i<=2e9;i=-~i){
bit=i;int cnt=0;
int le=ceil(log2(i))+(ceil(log2(i))==log2(i));
for(int j=0;j<=le-1;j=-~j)if(bit[j]&&((++cnt)<<1>le))break;
if((cnt<<1)<=le)ans++;
if(!(i%p)){
printf("%d,",ans-ansl),ansl=ans;
if(++cntl==40)putchar('\n'),cntl=0;//每40个数换行,方便观看。
}
}
return yhl;
}
码
#define yhl 0
#include"bits/stdc++.h"
using namespace std;
const int N=5e5;
bitset<33>bit;
int biao[4005]={
//此处省略100行打表代码
};
int l,r,ans;
bool check(int x){
if(!x)return 0;
int le=ceil(log2(x))+(ceil(log2(x))==log2(x));
bit=x;int cnt=0;
for(int i=0;i<le;i++)if(!bit[i])cnt++;
return ((cnt<<1)>=le);
}
int main(){
scanf("%d%d",&l,&r);
int bl=(l-1)/N+1,br=(r-1)/N+1;
if(bl^br){
for(int j=bl+1;j<=br-1;j++)ans+=biao[j];
for(int j=l;j<=bl*N;j++)ans+=check(j);
for(int j=br*N-N+1;j<=r;j++)ans+=check(j);
}else for(int i=l;i<=r;i++)ans+=check(i);
printf("%d",ans);
return yhl;
}
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步