首页 > 其他分享 >XOR Sum of Arrays

XOR Sum of Arrays

时间:2022-11-19 22:22:25浏览次数:51  
标签:XOR No Arrays Sum leq 异或 哈希 query oplus

section>

Problem Statement

For sequences $B=(B_1,B_2,\dots,B_M)$ and $C=(C_1,C_2,\dots,C_M)$, each of length $M$, consisting of non-negative integers, let the XOR sum $S(B,C)$ of $B$ and $C$ be defined as the sequence $(B_1\oplus C_1, B_2\oplus C_2, ..., B_{M}\oplus C_{M})$ of length $M$ consisting of non-negative integers. Here, $\oplus$ represents bitwise XOR.
For instance, if $B = (1, 2, 3)$ and $C = (3, 5, 7)$, we have $S(B, C) = (1\oplus 3, 2\oplus 5, 3\oplus 7) = (2, 7, 4)$.

You are given a sequence $A = (A_1, A_2, \dots, A_N)$ of non-negative integers. Let $A(i, j)$ denote the contiguous subsequence composed of the $i$-th through $j$-th elements of $A$.
You will be given $Q$ queries explained below and asked to process all of them.

Each query gives you integers $a$, $b$, $c$, $d$, $e$, and $f$, each between $1$ and $N$, inclusive. These integers satisfy $a \leq b$, $c \leq d$, $e \leq f$, and $b-a=d-c$. If $S(A(a, b), A(c, d))$ is strictly lexicographically smaller than $A(e, f)$, print Yes; otherwise, print No.

What is bitwise XOR? The exclusive logical sum $a \oplus b$ of two integers $a$ and $b$ is defined as follows.
  • The $2^k$'s place ($k \geq 0$) in the binary notation of $a \oplus b$ is $1$ if exactly one of the $2^k$'s places in the binary notation of $a$ and $b$ is $1$; otherwise, it is $0$.
For example, $3 \oplus 5 = 6$ (In binary notation: $011 \oplus 101 = 110$).
What is lexicographical order on sequences?

A sequence $A = (A_1, \ldots, A_{|A|})$ is said to be strictly lexicographically smaller than a sequence $B = (B_1, \ldots, B_{|B|})$ if and only if 1. or 2. below is satisfied.

  1. $|A|<|B|$ and $(A_{1},\ldots,A_{|A|}) = (B_1,\ldots,B_{|A|})$.
  2. There is an integer $1\leq i\leq \min\{|A|,|B|\}$ that satisfies both of the following.
    • $(A_{1},\ldots,A_{i-1}) = (B_1,\ldots,B_{i-1})$.
    • $A_i < B_i$.

Constraints

  • $1 \leq N \leq 5 \times 10^5$
  • $0 \leq A_i \leq 10^{18}$
  • $1 \leq Q \leq 5 \times 10^4$
  • $1 \leq a \leq b \leq N$
  • $1 \leq c \leq d \leq N$
  • $1 \leq e \leq f \leq N$
  • $b - a = d - c$
  • All values in the input are integers.

Input

The input is given from Standard Input in the following format, where $\text{query}_i$ represents the $i$-th query:

$N$ $Q$
$A_1$ $A_2$ $\dots$ $A_N$
$\text{query}_1$
$\text{query}_2$
$\vdots$
$\text{query}_Q$

The queries are in the following format:

$a$ $b$ $c$ $d$ $e$ $f$

Output

Print $Q$ lines. The $i$-th line should contain the answer to the $i$-th query.


Sample Input 1

4 5
1 2 3 1
1 3 2 4 1 4
1 2 2 3 3 4
1 1 2 2 3 4
1 2 2 3 3 3
1 4 1 4 1 1

Sample Output 1

No
No
Yes
No
Yes

For the first query, we have $A(1, 3) = (1, 2, 3)$ and $A(2, 4) = (2, 3, 1)$, so $S(A(1,3),A(2,4)) = (1 \oplus 2, 2 \oplus 3, 3 \oplus 1) = (3, 1, 2)$. This is lexicographcially larger than $A(1, 4) = (1, 2, 3, 1)$, so the answer is No.
For the second query, we have $S(A(1,2),A(2,3)) = (3, 1)$ and $A(3,4) = (3, 1)$, which are equal, so the answer is No.


Sample Input 2

10 10
725560240 9175925348 9627229768 7408031479 623321125 4845892509 8712345300 1026746010 4844359340 2169008582
5 6 5 6 2 6
5 6 1 2 1 1
3 8 3 8 1 6
5 10 1 6 1 7
3 4 1 2 5 5
7 10 4 7 2 3
3 6 1 4 7 9
4 5 3 4 8 9
2 6 1 5 5 8
4 8 1 5 1 9

Sample Output 2

Yes
Yes
Yes
Yes
No
No
No
No
No
No

很明显,是哈希的题。要判断哪个字典序大,可以通过二分找到第一个 \(i\) 使 \(a_i\ne b_i\) 然后判断 \(a_i\) 和 \(b_i\) 的大小。然后二分过程中只需要判断两个序列是否相同,就可以用哈希判断。

官方题解的做法太神奇,这里参考了大多赛时AC程序的方法。

首先如果把异或改成加法,就是使用经典的 Robin-Karp 哈希。以一个数 \(x\) 作为位权,定义一个序列 \(a_1,a_2\cdots a_k\) 的哈希值为 \(x^{k-1}a_1+x^{k-2}a_2\cdots xa_{k-1}+a_{k}\) 这个 \(x\) 可以随机取。然后易得序列 \(a_1+b_1,a_2+b_2\cdots a_k+b_k\) 的哈希值就是 \(a\) 序列的哈希值加上 \(b\) 序列的哈希值。所以判断是否是否相同就可以直接将前两个的哈希值相加判断是否与第三个序列相同。

但是异或呢?如果是异或的话,我们的哈希就完全不行了,因为乘法对异或没有分配律。我们要找一种运算对异或满足分配律的,想到与和或,但是他们都不支持幂次。

这个运算是矩阵乘法。不妨把一个二进制当作一个行向量。众所周知,正常矩阵乘法的形式是 $$c_{i,j}=\sum{a_{i,j}\times b_{j,k}}$$

然后把他修改成 $$c_{i,j}=\bigoplus a_{i,j}\and b_{j,k}$$
\(\bigoplus\) 仍然表示异或, \(\and\) 表示按位与。

根据矩阵的结论,由于按位与对异或有分配律,所以其实这样出来的矩阵具有结合律,对异或具有分配律。所以方法就是以一个随机01矩阵为位权。这样哈希时我们就可以直接将两个序列的哈希值异或起来,是与按位异或后的序列的哈希值相等。

但是这样一次矩阵乘法的复杂度是 \(log^3\),算上二分过不了?类似的以位运算为运算的矩阵乘法大多是可以压位的。观察上面的式子,如果 \(a_{i,j}=1,c_i^=b_j\)(c,b已经压成了二进制)。矩阵乘法复杂度降到 \(log^2\)

另外,由于矩阵满足分配律,所以可以预处理矩阵的幂后,可以像正常的哈希一样直接提取出区间 \([l,r]\) 的哈希值。但是我保险起见,打了一个倍增。这样更有可能对。

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL; 
const int N=5e5+5,M=63;
mt19937_64 gen(time(0));
struct matrix{
	int a[M];
	void init()
	{
		for(int i=0;i<M;i++)
			a[i]=1LL<<i;
	}
	matrix operator*(const matrix&b)const{
		matrix c;
		memset(c.a,0,sizeof(c.a));
		for(int i=0;i<M;i++)
			for(int j=0;j<M;j++)
				if(a[i]>>j&1)
					c.a[i]^=b.a[j];
		return c;
	}
	void operator=(matrix b){
		for(int i=0;i<M;i++)
			a[i]=b.a[i];
	}
}pw[25]; 
LL mul(LL x,matrix a)
{
	LL ret=0;
	for(int i=0;i<M;i++)
		if(x>>i&1)
			ret^=a.a[i];
	return ret;
}
LL x[N],st[25][N];
int n,q,a,b,c,d,e,f;
int main()
{
	scanf("%d%d",&n,&q);
	for(int i=0;i<M;i++)
		pw[0].a[i]=gen();
	for(int i=1;i<=n;i++)
		scanf("%lld",x+i),st[0][i]=x[i];
	for(int i=1;i<25;i++)
		pw[i]=pw[i-1]*pw[i-1];
	for(int i=1;i<25;i++)
		for(int j=1;j+(1<<i)-1<=n;j++)
			st[i][j]=st[i-1][j]^mul(st[i-1][j+(1<<i-1)],pw[i-1]);
	while(q--)
	{
		scanf("%d%d%d%d%d%d",&a,&b,&c,&d,&e,&f);
		int l=0;
		for(int i=24;i>=0;i--)
			if(a+l+(1<<i)<=b+1&&e+l+(1<<i)<=f+1&&(st[i][a+l]^st[i][c+l])==st[i][e+l])
				l+=1<<i;
		if(e+l>f)
			printf("No\n");
		else if(a+l>b)
			printf("Yes\n");
		else if((x[a+l]^x[c+l])<x[e+l])
			printf("Yes\n");
		else
			printf("No\n");
	}
}

标签:XOR,No,Arrays,Sum,leq,异或,哈希,query,oplus
From: https://www.cnblogs.com/mekoszc/p/16907309.html

相关文章

  • C. Sum of Substrings题解
    C.SumofSubstrings题目大概意思,给你一个01串,求和最小,其中和是该串所有相邻字符所组成的十进制数的和。如:0110,sum=01+11+10=22。通过观察我们可以发现,除了第......
  • F - Subarrays题解
    F-Subarrays题意:给你一个序列,问这个序列里有多少个子串的和能被k整除。思路:求前缀和,然后每个位置对k取模,模数相等的位置之间,是一个满足条件的字串。因为求的是前缀和,......
  • [数学记录]arc137D Prefix Xors
    FWT/高维前缀和入门题。题意:给定一个数列\(a\),每次迭代把原数组替代为前缀异或和数组,求经过\(1-m\)次操作后\(a_n\)的值。\(n\leq10^6\)。首先,无论是手推找规律还......
  • [LeetCode] 1099. Two Sum Less Than K
    Givenanarraynumsofintegersand integerk,returnthemaximumsumsuchthatthereexistsi<jwithnums[i]+nums[j]=sumandsum<k.Ifnoi,jexis......
  • [LeetCode] 891. Sum of Subsequence Widths
    Thewidthofasequenceisthedifferencebetweenthemaximumandminimumelementsinthesequence.Givenanarrayofintegersnums,returnthesumofthewi......
  • 1104 Sum of Number Segments
    Givenasequenceofpositivenumbers,asegmentisdefinedtobeaconsecutivesubsequence.Forexample,giventhesequence{0.1,0.2,0.3,0.4},wehave10......
  • Day15.1:Arrays类的详解
    Arrays类的详解首先Arrays是Java中的一个类,我们可以调用Arrays类的方法来方便我们对数组的使用Arrays类的方法都是static修饰的,可以直接按照类.方法名进行调用案例:利......
  • POJ 1845Sumdiv(数论)
    SumdivTimeLimit:1000MS MemoryLimit:30000KTotalSubmissions:20041 Accepted:5060DescriptionConsidertwonaturalnumbersAandB.LetSbethesumof......
  • 38:列表_排序_revered逆序_max_min_sum
    ###列表排序###修改原列表,不建新列表的排序>>>a=[20,10,30,40]>>>id(a)46017416>>>a.sort()#默认是升序排列>>>a[10,20,30,40]>>>a=[10,20,30,40]>>......
  • 【补题】The 2022 SDUT Summer Trials
    比赛链接The2022SDUTSummerTrialsA.Ginger'snumber样例恶臭(恼)签到题简单分解因数就会发现要求的就是\(gcd\),直接算即可,时间复杂度\(\Theta(Tlog(max(x,y)))\)......