B异或序列

原题链接

B异或序列

题目大意

题目将会给你 n n n ( 1 ≤ n ≤ 1000000 ) (1\le n\le 1000000) (1n1000000)个数字组成的数列 a a a ( a i ≤ 2 30 ) (a_i\le 2^{30}) (ai230),和一个 k k k ( 1 ≤ k ≤ 2 30 ) (1\le k\le 2^{30}) (1k230),请输出有多少组 i , j i,j i,j满足 a i a_i ai x o r xor xor a j = k a_j=k aj=k

解题思路

我们可以先来模拟一下:
( 11001011010010010111010010111 ) 2 (11001011010010010111010010111)_2 (11001011010010010111010010111)2 x o r xor xor ? = ( 11001011010010010111010100100 ) 2 ?=(11001011010010010111010100100)_2 ?=(11001011010010010111010100100)2
想要得到" ? ? ?",我们可以先分析一下。众所周知, a a a x o r xor xor k = b k=b k=b,那么, a a a x o r xor xor b = k b=k b=k,也就是说,在题目中,如果 a i a_i ai x o r xor xor a j = k a _j=k aj=k,那么 a i = a j a_i=a_j ai=aj x o r xor xor k k k,所以,我们可以遍历每个i,如果 a i a_i ai x o r xor xor a j = k a_j=k aj=k,中的 j j j存在,那么 a i a_i ai x o r xor xor k k k就必定存在与这个数列中。

优化

但是,你会发现,如果真的把数组开到 2 30 2^{30} 230的话,就会MLE(Memory Limit Exceeded),这时,我们便需要使用哈希算法进行优化。

哈希

题目给了你一个数列,我们想要把它们存下来,我们可以使用一个表,和一个质数,每个数都进行模运算,并将这个数存在下标为模运算结果的那个格子中(如果已经被占用,就往后推,直到找到第一个空的格子,再存进去)。
举个例子:
有10个数,分别是
1,3,5,6,7,9,10,12,13,20
选择的质数是17,那么我们来模拟一下存表的过程:

  1. 1 1 1 m o d mod mod 17 = 1 17=1 17=1
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
  1. 3 3 3 m o d mod mod 17 17 17
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
0 1 0 3 0 0 0 0 0 0 0 0 0 0 0 0 0
  1. 5 5 5 m o d mod mod 17 = 5 17=5 17=5
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
0 1 0 3 0 5 0 0 0 0 0 0 0 0 0 0 0
  1. 6 6 6 m o d mod mod 17 = 6 17=6 17=6
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
0 1 0 3 0 5 6 0 0 0 0 0 0 0 0 0 0
  1. 7 7 7 m o d mod mod 17 = 7 17=7 17=7
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
0 1 0 3 0 5 6 7 0 0 0 0 0 0 0 0 0
  1. 9 9 9 m o d mod mod 17 = 9 17=9 17=9
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
0 1 0 3 0 5 6 7 0 9 0 0 0 0 0 0 0
  1. 10 10 10 m o d mod mod 17 = 10 17=10 17=10
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
0 1 0 3 0 5 6 7 0 9 10 0 0 0 0 0 0
  1. 12 12 12 m o d mod mod 17 = 12 17=12 17=12
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
0 1 0 3 0 5 6 7 0 9 10 0 12 0 0 0 0
  1. 13 13 13 m o d mod mod 17 = 13 17=13 17=13
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
0 1 0 3 0 5 6 7 0 9 10 0 12 13 0 0 0
  1. 20 20 20 m o d mod mod 17 = 3 17=3 17=3
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
0 1 0 3 0 5 6 7 0 9 10 0 12 13 0 0 0

由于3的位置已经有了数字,所以,往后推,找到的第一给空的位置,也就是4,再存入数组:

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
0 1 0 3 20 5 6 7 0 9 10 0 12 13 0 0 0

代码实现

#include<bits/stdc++.h>
#define hash_number 2100001//大质数,存储时使用
using namespace std;
long long c[hash_number],a[hash_number],ans,n,k,t;
int hash1(long long x)
{
    
    
	int i=x%hash_number;
	while(c[i]&&a[i]!=x)//哈希查找
	{
    
    
		i++;//找到的位置存储再i中
		if(i==hash_number) i=0;
	}
	return i;
}
int main()
{
    
    
	cin>>n>>k;
	for(int i=1;i<=n;i++){
    
    
		cin>>t;
		ans+=c[hash1((t^k))];
		int t_to_hash=hash1(t);
		a[t_to_hash]=t;
		c[t_to_hash]++;
	}
	cout<<ans*2;//因为就像5 xor 4=1一样,应该统计两次(4 xor 5=1)
}

输入格式

第一行有两个整数,分别为 n ( 1 ≤ n ≤ 1000000 ) n(1\le n\le 1000000) n(1n1000000) k ( 1 ≤ k ≤ 2 30 ) k(1\le k\le 2^{30}) k(1k230)
第二行有 n n n个数,分别为 a 1 a_1 a1 a n a_n an

输出格式

只有一个数,为满足 a i a_i ai x o r xor xor a j = k a_j=k aj=k i i i j j j 的组数。

样例

输入

5 1
1 4 2 2 5

输出

2

样例解释

两组分别为 ( a 2 , a 5 ) (a_2,a_5) (a2,a5) ( a 5 , a 2 ) (a_5,a_2) (a5,a2),也就是 4 4 4 x o r xor xor 5 = 1 5=1 5=1 5 5 5 x o r xor xor 4 = 1 4=1 4=1

猜你喜欢

转载自blog.csdn.net/weixin_41247488/article/details/120610562