[300iq]Bitwise Xor

Posted StaroForgin

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[300iq]Bitwise Xor相关的知识,希望对你有一定的参考价值。

Bitwise Xor

题解

首先我们可以发现一个性质,若 x < y < z x<y<z x<y<z,那么一定有 x ⊕ z ⩾ min ⁡ ( x ⊕ y , y ⊕ z ) x\\oplus z\\geqslant \\min(x\\oplus y,y\\oplus z) xzmin(xy,yz)
这个结论可以从二进制的角度分析 x ⊕ y x\\oplus y xy y ⊕ z y\\oplus z yz的异或过程得出。
显然二进制的比较可以从高位到低位依次比较。
如果 x ⊕ y x\\oplus y xy y ⊕ z y\\oplus z yz在这一位上都是 0 0 0,显然, x ⊕ z x\\oplus z xz有这两种异或起来也应该是 0 0 0,这个位置两者没有区别,我们会继续往下比较,这部分也象征着 x , y , z x,y,z x,y,z在这前面几位都是一样的。
x ⊕ y x\\oplus y xy y ⊕ z y\\oplus z yz其中有一个 1 1 1,那么 x ⊕ z x\\oplus z xz这一位也应该是 1 1 1,比是 0 0 0的那一个大,此时便已经符合我们的条件了。
x ⊕ y x\\oplus y xy y ⊕ z y\\oplus z yz两个都是 1 1 1,要么 y y y在这一位上为 1 1 1 x , z x,z x,z在这一位上为 0 0 0,要么反过来, x , z x,z x,z 1 1 1 y y y 0 0 0
但由于 z > y z>y z>y,所以 z z z肯定在前面的某一位比 y y y大,故它应该在之前就进入了前一种情况,不会比较到这里,第一种方案被否决。
同理 y > x y>x y>x,第 2 2 2种方案也被否决。
所以它们一定会在第 2 2 2种情况决出胜负,所以一定有上面的条件成立。

有了上面的性质,我们可以发现,如果我们已经有了一个满足答案的集合 S S S,那么 w w w只要与 S S S中离它最近的两个数异或起来比 x x x大,那么它一定与 S S S中所有数异或起来都比 x x x大。
2 2 2个数显然不好记录,但我们可以从小到大依次加入 a i a_i ai,这样的话每次加入的 a i a_i ai一定是最大的,只需要与集合中最大的一个数比较大小,只要与这个数异或起来大于 x x x就行了。
我们记 d p i dp_i dpi表示最大值为 a i a_i ai的合法集合的个数,我们转移 d p j dp_j dpj时,只需要找到 a j ⊕ a i ⩾ x a_j\\oplus a_i\\geqslant x ajaix的所有 a i a_i ai,加上 d p i dp_i dpi的和就可以转移了。
显然找到 a i ⊕ a j ⩾ x a_i\\oplus a_j\\geqslant x aiajx d p i dp_i dpi和可以使用 T r i e Trie Trie树上,每次只会查询一条链,再将新的插入进去即可。

时间复杂度 O ( n log ⁡ a ) O\\left(n\\log a\\right) O(nloga)

源码

#include<bits/stdc++.h>
using namespace std;
#define MAXN 300005
#define lowbit(x) (x&-x)
#define reg register
#define pb push_back
#define mkpr make_pair
#define fir first
#define sec second
typedef long long LL;
typedef unsigned long long uLL; 
typedef long double ld;
typedef pair<int,int> pii;
const int INF=0x3f3f3f3f;
const int mo=998244353;
const int mod=1e5+3;
const int inv2=5e8+4;
const int jzm=2333;
const int zero=20000;
const int n1=1000;
const int M=100000;
const int orG=3,ivG=332748118;
const long double Pi=acos(-1.0);
const double eps=1e-12;
template<typename _T>
_T Fabs(_T x)return x<0?-x:x;
template<typename _T>
void read(_T &x)
	_T f=1;x=0;char s=getchar();
	while(s>'9'||s<'0')if(s=='-')f=-1;s=getchar();
	while('0'<=s&&s<='9')x=(x<<3)+(x<<1)+(s^48);s=getchar();
	x*=f;

template<typename _T>
void print(_T x)if(x<0)x=(~x)+1;putchar('-');if(x>9)print(x/10);putchar(x%10+'0');
int gcd(int a,int b)return !b?a:gcd(b,a%b);
int add(int x,int y,int p)return x+y<p?x+y:x+y-p;
void Add(int &x,int y,int p)x=add(x,y,p);
int qkpow(int a,int s,int p)int t=1;while(s)if(s&1)t=1ll*t*a%p;a=1ll*a*a%p;s>>=1;return t;
int n,root,dp[MAXN],ans;LL X,a[MAXN];
struct mingint sum,ch[2];;
class TrieTree
	private:
		ming tr[MAXN*70];int tot;
	public:
		void insert(int &rt,int dp,LL val,int aw)
			if(!rt)rt=++tot;Add(tr[rt].sum,aw,mo);if(dp<0)return ;
			insert(tr[rt].ch[(val>>dp)&1LL],dp-1,val,aw);
		
		int query(int &rt,int dp,LL val)
			if(!rt)return 0;if(dp<0)return tr[rt].sum;
			int res=0,typ=(int)((val>>dp)&1LL);
			if((X>>dp)&1LL)Add(res,query(tr[rt].ch[typ^1],dp-1,val),mo);
			else Add(res,tr[tr[rt].ch[typ^1]].sum,mo),
				Add(res,query(tr[rt].ch[typ],dp-1,val),mo);
			return res;
		
T;
signed main()
	read(n);read(X);
	for(int i=1;i<=n;i++)read(a[i]);
	sort(a+1,a+n+1);
	for(int i带有 ufunc bitwise_xor 的 TypeError

codeforces gym 102268 300iq round

CF778B(round 402 div.2 E) Bitwise Formula

「题解」300iq Contest 2 H. Honorable Mention

[300iq contest1-J]Jealous Split

如何使用OpenCV作图像或矩阵的逻辑运算