毒瘤xor

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32768K,其他语言65536K
Special Judge, 64bit IO Format: %lld

在这里插入图片描述

输入描述:
第一行一个整数N,表示序列的长度
第二行N个整数,表示序列内的元素
第三行一个整数q,表示询问的个数
接下来q行,每行两个整数[L, R],表示询问的区间
输出描述:
输出q行,每行一个整数表示答案

若有多组可行解,请输出较小的解

输入

5
4 78 12 1 3
3
2 5
1 4
3 3

输出

2147483632
2147483635
2147483635

思路:核心:贪心+前缀和
要让异或的结果尽可能的大,也就是尽量让每一位都是1。
自己举例后可以发现,当位置上1的数量多时,要去异或0,才能让结果为1,位置上0的数量多时,就要去异或1,让结果为1,优先满足大多数嘛~
因为结果相同时输出小的数,所以当0和1数量相同时,去异或0。自己做的时候用一下计算器,验证答案。
(代码有注释

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

typedef long long ll;

int arr[100005][34];//前缀和 
int b[34];//存  去异或  的那个数的二进制 
int main()
{
	int i,n,j,t;
	ll x;
	cin>>n;
	for(i=1;i<=n;i++)
	{
		cin>>x;
		for(j=0;j<31;j++)
		{
			arr[i][j]=(x>>j)&1;//输入,存末尾数字 
		}
	}
	
	for(i=1;i<=n;i++)
	for(j=0;j<31;j++)
	arr[i][j]+=arr[i-1][j];//前缀和一波 
	
	cin>>t;
	while(t--)
	{
	ll x,y;// 
	ll result=0;//结果 
	memset(b,0,sizeof(b));//每组新数据要清数组 
	cin>>x>>y;
	cin.clear(); 
	if(x==y)//如果区间只有一个数,特判 
	for(i=0;i<31;i++)	b[i]=!(arr[x][i]-arr[x-1][i]);
	
	else
	for(i=0;i<31;i++)
	{
		if((arr[y][i]-arr[x-1][i])>(y-x)/2)	b[i]=0;//如果0多,异或1 
		else b[i]=1;//反之 
	}
	for(i=31;i>=0;i--)	result+=b[i]*pow(2,i);//二转十 ,用一波pow 
	cout<<result<<endl;//输出结果 
	}
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值