这题和上次做的Uva11361和相似,也是区间查询,利用前缀数组来存,结果为a[r]-a[l-1]。
这题注意转化为求每一位的1的个数和。
做题时遇到一个小的问题,(0<<1)=0,调试了好久,以后得注意了。
代码:
#include<iostream> #include<cstdio> #include<cmath> #include<cstring> #define ll __int64 using namespace std; void fun(int x,ll *a) { if(x<=0) { return ; } int d=0,tx=x; while(tx) { tx/=2; d++; } for(int i=d; i>=1; i--) { if(i==1) { if(x&1) a[i]+=1; continue; } if(x&((int)(pow(2.0,i-1)))) { a[i]+=(1+x%((int)pow(2.0,i-1))); for(int j=i-1; j>=1; j--) { a[j]+=pow(2,i-2); } x-=(int)pow(2.0,i-1); } } } int main() { int l,r; ll x[66]; ll y[66]; while(scanf("%d%d",&l,&r)!=EOF) { memset(x,0,sizeof(x)); memset(y,0,sizeof(y)); fun(l-1,x); fun(r,y); ll sum=0,tmp=0,a; for(int i=1; i<64; i++) { a=y[i]-x[i]; tmp=(tmp+a)/2; sum+=tmp; } printf("%I64d\n",sum); } return 0; }