首页 > 其他分享 >【XSY3313】异或和(xorsum)(结论)

【XSY3313】异或和(xorsum)(结论)

时间:2022-10-30 11:14:25浏览次数:55  
标签:XSY3313 ch ll cdots mid 异或 序列 xorsum

先上一个结论。

  • 一个长度为 \(n\) 的 \(01\) 序列,其每个子序列的异或和的和为 \([序列中包含 1]2^{n-1}\)。

证明:考虑若不存在 \(1\),则显然。否则若存在 \(1\),随便选一个 \(1\) 出来,不失一般性地设为第 \(1\) 位,然后考虑第 \(2\sim n\) 位的某个子序列的异或和 \(s\),第 \(1\) 位的 \(1\) 有且仅有一种选取方式使得 \(s\) 变为 \(1\)。故整个序列每个子序列的异或和的和就是第 \(2\sim n\) 位的子序列个数 \(2^{n-1}\)。

那么按位考虑之后,\(f(a_1,a_2,\cdots,a_n)=(a_1|a_2|\cdots|a_n)\times 2^{n-1}\)。于是题目相当于询问从 \([l,r]\) 中选 \(n\) 个数或起来能得到多少种不同的结果。

再来一个结论。

  • \(n>2\) 和 \(n=2\) 没有区别。

证明:

首先 \(n=2\) 时得到的结果一定被 \(n>2\) 时得到的结果包含,于是我们只需考虑任意一种 \(n>2\) 的结果都能被构造成两个数 \(a,b\in[l,r]\) 的或。

设 \(l,r\) 最高不同位为 \(h\),\(mid=2^{h}\),那么我们把 \([l,r]\) 分成 \([l,mid-1]\)(它们第 \(h\) 位都为 \(0\))和 \([mid,r]\)(它们第 \(h\) 位都为 \(1\)),考虑 \(n>2\) 时的选取情况:

  • 若选了 \([l,mid-1]\) 中的某个数,那么 \(a_1|a_2|\cdots|a_n\) 的第 \(0\sim h-1\) 位所组成的数 \(x\) 一定大于等于 \(l\),那么就一定有 \(x\in [l,mid-1]\),于是先令 \(a\gets x\),然后再视 \(a_1|a_2|\cdots|a_n\) 第 \(h\) 位是否为 \(1\) 来考虑 \(b\gets mid\) 或 \(b\) 不选。
  • 若没有选 \([l,mid-1]\) 中的任意一个数,即只选了 \([mid,r]\) 中的数。那么设 \(r\) 除了第 \(h\) 位以外的最高位为第 \(h'\) 位(\(r\) 的次高位),那么 \(a_1|a_2|\cdots|a_n\in [mid,mid+2^{h'+1})\),设 \(a_1|a_2|\cdots|a_n\) 第 \(0\sim h'-1\) 位所组成的数为 \(x\),那么先令 \(a\gets mid+x\),然后再视 \(a_1|a_2|\cdots|a_n\) 第 \(h'\) 位是否为 \(1\) 来考虑 \(b\gets mid+2^{h'}\) 或 \(b\) 不选。

证毕。

证明的过程同时也得到了 \(a|b\) 的取值范围,于是分类讨论一下即可。

#include<bits/stdc++.h>

#define ll long long

using namespace std;

inline ll read()
{
	ll x=0;
	int f=1;
	char ch=getchar();
	while(ch<'0'||ch>'9')
	{
		if(ch=='-') f=-1;
		ch=getchar();
	}
	while(ch>='0'&&ch<='9')
	{
		x=(x<<1)+(x<<3)+(ch^'0');
		ch=getchar();
	}
	return x*f;
}

int T,n;

inline ll lowbit(ll x)
{
	return x&-x;
}

int main()
{
	T=read();
	while(T--)
	{
		n=read();
		ll l=read(),r=read();
		if(n==1)
		{
			printf("%lld\n",r-l+1);
			continue;
		}
		if(l==r)
		{
			puts("1");
			continue;
		}
		ll y=l^r;
		int hb;
		for(hb=63;hb>=0;hb--)
			if((y>>hb)&1) break;
		ll z=(1ll<<(ll)(hb+1))-1;
		l&=z,r&=z;
		ll mid=(1ll<<(ll)hb);
		ll ans=(mid-l)<<1ll;
		r^=mid;
		int hbb=hb;
		for(;hbb>=0;hbb--)
			if((r>>hbb)&1ll) break;
		ll x=(1ll<<(ll)(hbb+1))-1;
		ans+=min(x,l-1)+1;
		printf("%lld\n",ans);
	}
	return 0;
}
/*
3
3 3 4
2 10 11
3 1 3
*/
/*
1
5 7 33
*/

标签:XSY3313,ch,ll,cdots,mid,异或,序列,xorsum
From: https://www.cnblogs.com/ez-lcw/p/16840747.html

相关文章

  • 不借助第三个变量,交换两个数。(使用异或^)
    packageclass02;importjava.util.Arrays;/***不借助第三个变量,交换两个数。(使用异或^)*异或(^):相同为0,不同为1。*记为:无进位相加。*/publicclassCod......
  • 1879. 两个数组最小的异或值之和
    题目描述给了两个数组nums1和nums2,长度都是n,问怎么排列可以让数组对应元素的异或值之和最小?f1-二进制枚举+状态压缩基本分析1.有没有是啥贪心做法,因为看到相同元素异或......
  • 力扣(leetcode) 231. 2 的幂(暴力枚举解法)(二进制异或解法)
    题目在这:https://leetcode-cn.com/problems/power-of-two/题目分析:题目比较好理解,给了一个数N,让你找一个数X,使得n==2的X次方。法一:直接想到的暴力枚举法。上代码:n=5......
  • 线性基基础入门|求线性基|最大异或和|第k大异或和|判断一个数能否用线性基表示
    前置知识:(今天刚知道的#acm:异或满足结合律,交换律,x^x=0;#线性代数关于最大无关组的基本知识-------我是正文------给定一个数组a1,a2,a3,a4,a5..数组a的线性基b为b1......
  • c语言异或(c语言异或符号)
    请帮我讲解一下C语言中的异或运算首先,我们看一下异或的原理:a = 3 ^ 5;3的二进制是0011,5的二进制是0101。异或发现两者的不同之处,所以a最终为0110b(4)。了解了异或的基本......
  • CF1322B Present & P3760 [TJOI2017] 异或和
    CF1322B考虑每一位的贡献,记当前位为\(k\)显然高位不会影响低位,那么将所有数\(\bmod2^{k+1}\)那么第\(k\)位为\(1\)当且仅当\(2^k\lea'_i+a'_j<2^{k+1}\)或......
  • 学习日记(异或运算)
    1、136、只出现一次的数字classSolution{public:intsingleNumber(vector<int>&nums){intret=0;for(autoe:nums)ret^=e;/*for(aut......
  • 【LeetCode】1486. 数组异或操作(C++)
    1486.数组异或操作(C++)​​1题目描述​​​​2示例描述​​​​2.1示例1​​​​2.2示例2​​​​2.3示例3​​​​2.4示例4​​​​3解题提示​​​​4源码详......
  • 如何理解异或?
    异或的运算法则为:0⊕0=0,1⊕0=1,0⊕1=1,1⊕1=0(同为0,异为1)知乎上一位朋友是这么理解的:男性和女性能生出孩子,否则就不行。有兴趣可以去看看:https://www.zhihu.com/question/31......
  • 做题记录整理数据结构2 P4551 最长异或路径(2022/10/13)
    P4551最长异或路径其实我也不知道算不算数据结构,反正就是01trie,不过题目本身似乎也是一个模板?https://www.luogu.com.cn/blog/108510/solution-p4551(由于一看到异或就......