[QZSOJ4968]最大值

这篇博客介绍了如何针对不同运算(异或、或、与)在给定的整数集合中选择两个数以最大化操作结果。使用了trie树、贪心策略和位运算技巧,分别提供了O(σn)的时间复杂度解决方案。

description

给定 nnn 个数 {ai}\{a_i\}{ai},要求从中选出两个不同的数 x,yx,yx,y,使得 x op yx\ op\ yx op y 最大。

op=or,xor,andop=or,xor,andop=or,xor,and

n≤106,ai≤106n\leq 10^6,a_i\leq10^6n106,ai106

solution

  • xorxorxor

我们对于所有的数二进制形式建一棵 trietrietrie,然后枚举一个数,在另一个上面贪心做就好了

O(σn)O(\sigma n)O(σn)

  • ororor

考虑枚举每一个数,然后对于 000 的位,看有没有一个数能够依次满足从高到低的每一位,如果有就填上,如果没有就空过去

O(σn)O(\sigma n)O(σn)

  • andandand

从高到低枚举每一位,如果这一位上现在可以选的为 111 的数量 ≥2\geq 22 就选上,删掉所有这一位是 000 的,否则不管

O(σn)O(\sigma n)O(σn)

#include<iostream>
#include<cstring>
#include<cassert>
#include<cmath>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<cstdio>
#include<vector>
#include<time.h>
#include<algorithm>
#include<climits>

using namespace std;

# define Rep(i,a,b) for(register int i=a;i<=b;i++)
# define _Rep(i,a,b) for(register int i=a;i>=b;i--)
# define RepG(i,u) for(int i=head[u];~i;i=e[i].next)

typedef long long ll;

const int N=(1<<20)+5;

template<typename T> void read(T &x){
   x=0;int f=1;
   char c=getchar();
   for(;!isdigit(c);c=getchar())if(c=='-')f=-1;
   for(;isdigit(c);c=getchar())x=(x<<1)+(x<<3)+c-'0';
    x*=f;
}

int t,n,op;

namespace And{
	int a[N];
	bool flag[N];
	void solve(){
		Rep(i,1,n)read(a[i]),flag[i]=true;
		int res=0;
		_Rep(s,19,0){
			int cnt=0;
			Rep(i,1,n)
				if(a[i]>>s&1&&flag[i])cnt++;
			if(cnt>=2){
				res|=1<<s;
				Rep(i,1,n)
					if(!(a[i]>>s&1))flag[i]=false;	
			}	
		}
		printf("%d\n",res);
	}
}

namespace Or{
	int a[N],sum[N];
	void solve(){
		memset(sum,0,sizeof(sum));
		Rep(i,1,n)read(a[i]),sum[a[i]]++;
		int res=0;
		Rep(s,0,19)
			for(int i=0;i<1<<20;i++)
				if(i>>s&1)sum[i^(1<<s)]+=sum[i];
		Rep(i,1,n){
			int now=a[i],yuzuki=0;
			_Rep(s,19,0){
				if(now>>s&1)continue;
				yuzuki|=1<<s;
				if(!sum[yuzuki])yuzuki^=1<<s;
			}
			now|=yuzuki;
			res=max(res,now);
		}
		printf("%d\n",res);
	}
}

namespace Xor{
	int trie[N][2],tot;
	int a[N];
	void insert(int x){
		int u=0;
		_Rep(i,19,0){
			int j=x>>i&1;
			if(!trie[u][j])trie[u][j]=++tot;
			u=trie[u][j];
		}
	}
	int ask(int x){
		int u=0,res=0;
		_Rep(i,19,0){
			int j=x>>i&1;
			j^=1;
			if(trie[u][j]){
				res|=1<<i;
				u=trie[u][j];	
			}
			else u=trie[u][j^1];
		}
		return res;
	}
	void solve(){
		memset(trie,0,sizeof(trie));
		tot=0;
		int res=0;
		Rep(i,1,n)read(a[i]),insert(a[i]);
		Rep(i,1,n)res=max(res,ask(a[i]));
		printf("%d\n",res);
	}
}

int main()
{
	read(t);
	while(t--){
		read(n),read(op);
		if(op==1)And::solve();
		if(op==2)Xor::solve();
		if(op==3)Or::solve();
	}
	return 0;
}
/*
3
5 1
1 4 5 7 9
5 2
2 3 4 5 7
5 3
9 5 4 2 1

*/
这是一个基于AI视觉识别与3D引擎技术打造的沉浸式交互圣诞装置。 简单来说,它是一棵通过网页浏览器运行的数字智慧圣诞树,你可以用真实的肢体动作来操控它的形态,并将自己的回忆照片融入其中。 1. 核心技术组成 这个作品是由三个尖端技术模块组成的: Three.js 3D引擎:负责渲染整棵圣诞树、动态落雪、五彩挂灯和树顶星。它创建了一个具备光影和深度感的虚拟3D空间。 MediaPipe AI手势识别:调用电脑摄像头,实时识别手部的21个关键点。它能读懂你的手势,如握拳、张开或捏合。 GSAP动画系统:负责处理粒子散开与聚合时的平滑过渡,让成百上千个物体在运动时保持顺滑。 2. 它的主要作用与功能 交互式情感表达: 回忆挂载:你可以上传本地照片,这些照片会像装饰品一样挂在树上,或者像星云一样环绕在树周围。 魔法操控:握拳时粒子迅速聚拢,构成一棵挺拔的圣诞树;张开手掌时,树会瞬间炸裂成星光和雪花,照片随之起舞;捏合手指时视线会拉近,让你特写观察某一张选中的照片。 节日氛围装饰: 在白色背景下,这棵树呈现出一种现代艺术感。600片雪花在3D空间里缓缓飘落,提供视觉深度。树上的彩色粒子和白色星灯会周期性地呼吸闪烁,模拟真实灯串的效果。 3. 如何使用 启动:运行代码后,允许浏览器开启摄像头。 装扮:点击上传照片按钮,选择温馨合照。 互动:对着摄像头挥动手掌可以旋转圣诞树;五指张开让照片和树化作满天星辰;攥紧拳头让它们重新变回挺拔的树。 4. 适用场景 个人纪念:作为一个独特的数字相册,在节日陪伴自己。 浪漫惊喜:录制一段操作手势让照片绽放的视频发给朋友。 技术展示:作为WebGL与AI结合的案例,展示前端开发的潜力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值