LOJ#6087. 毒瘤题(异或)

Posted Harris-H

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LOJ#6087. 毒瘤题(异或)相关的知识,希望对你有一定的参考价值。

LOJ#6087. 毒瘤题(异或)

注意到 k = 1 ∣ ∣ k = 2 k=1||k=2 k=1k=2

显然分情况讨论即可。

k = 1 k=1 k=1,答案就是异或和。

k = 2 k=2 k=2,所有数的异或和就是 s u m = x ⊕ y sum =x\\oplus y sum=xy

考虑 s u m sum sum 1 1 1的位,显然 x , y x,y x,y在该位一个为 1 1 1,一个为 0 0 0

所以我们预处理 a [ i ] a[i] a[i] 表示该位为 1 1 1 的数异或和,这样其他数都出现奇数次,得到的数就是 x , y x,y x,y中其中一个,然后 x ⊕ s u m = y x\\oplus sum=y xsum=y

时间复杂度: O ( l o g A ) O(logA) O(logA)

// Problem: #6087. 毒瘤题
// Contest: LibreOJ
// URL: https://loj.ac/p/6087
// Memory Limit: 4 MB
// Time Limit: 1000 ms
// Date: 2022-01-03 11:33:06
// --------by Herio--------

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull; 
const int N=1e3+5,M=2e4+5,inf=0x3f3f3f3f,mod=1e9+7;
const int hashmod[4] = 402653189,805306457,1610612741,998244353;
#define mst(a,b) memset(a,b,sizeof a)
#define PII pair<int,int>
#define PLL pair<ll,ll>
#define x first
#define y second
#define pb emplace_back
#define SZ(a) (int)a.size()
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define per(i,a,b) for(int i=a;i>=b;--i)
#define ios ios::sync_with_stdio(false),cin.tie(nullptr) 
void Print(int *a,int n)
	for(int i=1;i<n;i++)
		printf("%d ",a[i]);
	printf("%d\\n",a[n]); 

template <typename T>		//x=max(x,y)  x=min(x,y)
void cmx(T &x,T y)
	if(x<y) x=y;

template <typename T>
void cmn(T &x,T y)
	if(x>y) x=y;

//if have char input #define should cancel
#define getchar()(p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
char buf[1<<21],*p1=buf,*p2=buf;
template <typename T>
inline T& read(T& r) 
    r = 0; bool w = 0; char ch = getchar();
    while(ch < '0' || ch > '9') w = ch == '-' ? 1 : 0, ch = getchar();
    while(ch >= '0' && ch <= '9') r = r * 10 + (ch ^ 48), ch = getchar();
    return r = w ? -r : r;


template<class T>
inline void write(T x)

	if(!x)putchar('0');if(x<0)x=-x,putchar('-');
	static int sta[25];int tot=0;
	while(x)sta[tot++]=x%10,x/=10;
	while(tot)putchar(sta[--tot]+48);

int a[33];
int main()
	int n,k,x;
	read(n),read(k);
	if(k==1)
		k=0;rep(i,1,n) read(x),k^=x;
		printf("%d\\n",k);
	
	else 
		k=0;rep(i,1,n)
			read(x);k^=x;
			for(int j=0;j<=30;j++) if(x>>j&1) a[j]^=x;
		
		for(int j=0;j<=30;j++) if(k>>j&1)
			int u = a[j], v = u^k;
			if(u>v) swap(u,v);
			printf("%d %d\\n",u,v);
			return 0;
		
	
	return 0;


以上是关于LOJ#6087. 毒瘤题(异或)的主要内容,如果未能解决你的问题,请参考以下文章

[LOJ#114]k 大异或和

[LOJ#113]最大异或和

A Horrible Poem

[毒瘤题]玛里苟斯:线性基,表达式分析,测试点分治

loj6157 A^B Problem (并查集)

[loj3048]异或粽子