$\quad $ 想不出來了,遂打表。
$\quad $ 受到了luobotianle的啟發,就依據其建議學上了分塊打表。
如0與1的熟練
$\quad $ 問 \(L\) 到 \(R\) 之間,在二進位制表示下(無前導\(0\)),\(0\) 的個數比 \(1\) 的個數多的數的個數。
$\quad $ 那麼我們就可以以 \(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;
}