UVALive 6918 And Or 数学二进制+枚举

1<=L<=R<=1e18

求L & (L+1) &  (L+2)  & (L+3) ……  &  R

和L | (L+1) |  (L+2) | (L+3) …… |  R


这个题呢,让我自己做,肯定就是弃疗了,学习了一份二进制枚举的代码其实还是蛮简单的

拿第x位的二进制位置距离,要想在x上,&运算有值,那么就需要【L,R】的每一位二进制x都有值

就是说,【1,R】上二进制x位置上的个数 - 【1,L-1】 的x位置上的个数 = R-L+1

同理,|  运算,需要的是至少有一个,【1,R】上二进制x位置上的个数 - 【1,L-1】 的x位置上的个数 >=1


所以,枚举每一个二进制位,然后暴力统计就好了

#include<bits/stdc++.h>
using namespace std;

#define LL long long
LL cnt[70],ans1,ans2;

void calc(LL x,int f){
	for(int i=63;i>=0;i--)
		if ((x>>i)&1){
			cnt[i]+=f*(x%(1LL<<i)+1);
			for(int j=i-1;j>=0;j--)
				cnt[j]+=f*(1LL<<(i-1));
		}
}

void solve(LL a,LL b){
	memset(cnt,0,sizeof(cnt));
	calc(b,1);
	if (a>1) calc(a-1,-1);
	ans1=ans2=0;
	int t1,t2;
	for(int i=63;i>=0;i--){
		t1=t2=0;
		ans1<<=1;
		ans2<<=1;
		if (cnt[i]) ans1++;
		if (cnt[i]==b-a+1) ans2++;
	}
}

int main(){
	//freopen("input.txt","r",stdin);
	LL a,b;
	int T;
	scanf("%d",&T);
	for(int Case=1;Case<=T;Case++){
		scanf("%lld%lld",&a,&b);
		solve(a,b);
		printf("Case %d: %lld %lld\n",Case,ans1,ans2);
	}
	return 0;
}


全部评论

相关推荐

10-05 23:02
东北大学 Java
我说句实话啊:那时候看三个月培训班视频,随便做个项目背点八股,都能说3 40w是侮辱价
点赞 评论 收藏
分享
11-01 08:48
门头沟学院 C++
伤心的候选人在吵架:佬你不要的,能不能拿户口本证明过户给我。。球球了
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务