P5283 [十二省联考 2019] 异或粽子题解

Describtion

区间异或和前 kkk 大的和。


考虑一个异或的性质-----前缀异或和。

那当我们把权值前缀异或和下来,区间异或和变成了在一个长度为 n+1n+1n+1 的前缀异或和序列里选择一对异或起来。

接着我们该考虑如何去除 l,rl,rl,r 和 r,lr,lr,l 这种本质相同的对子重复算的贡献。

考虑我们直接算前 2∗k2*k2∗k 大的对子,答案最后除以2,这样显然是对的,思考一下。

接着我们按照正常的思路建出Trie树,开一个优先队列。

里面分别存 依照哪个值,在这个值的所有异或可能中他处于第几大,还有这一对的异或和。

开始时,把每个点能找到的最大的对子塞进优先队列。

循环 2∗k2*k2∗k 次,每次拿出最优的那个,加上其权值。

然后把他的次优的那个加进优先队列里面。

比如弹出来了一个{ 1,5,45378989354 }。就是参加于第一个对子,这是这个1的第5大的权值,权值为45378989354。

那么下一个也就是1的第6大的是很有希望成为答案的,所以就把他加进来。

这个仔细想想正确性显然。

代码这块

复制代码
cpp

#include <bits/stdc++.h>
#define ll long long
#define int long long
#define db(x) do{ cerr<<x<<' '; }while(0)
// #define linux
using namespace std;
#ifdef linux
	#define getchar getchar_unlocked
#endif
inline ll read(){
	ll x=0;int f=1;
	char c=getchar();
	while(c<'0'||c>'9'){
		if(c=='-') f=-1;
		c=getchar();
	}
	while(c>='0'&&c<='9'){
		x=x*10+c-'0';
		c=getchar();
	}
	return x*f;
}
void fre(){
	freopen("a.in","r",stdin);
	freopen("a.out","w",stdout);
}
const int N=500010;
struct node{ int id,k; ll w; bool operator <(const node &a)const{return w<a.w;} };
int n,k,a[N],tr[N*35][2],siz[N*35],idx;
ll s[N];
void insert(ll x){
	int p=0;
	for(int j=31;j>=0;j--){
		bool c=x&(1ll<<j);
		siz[p]++;
		if(!tr[p][c]) tr[p][c]=++idx;
		p=tr[p][c];
	}
	siz[p]++;
}
ll query(ll x,int k){
	int p=0;
	ll ans=0;
	for(int j=31;j>=0;j--){
		bool c=x&(1ll<<j);
		c=!c;
		if(!tr[p][c]) p=tr[p][!c];
		else if(k<=siz[tr[p][c]]) p=tr[p][c],ans|=(1ll<<j);
		else k-=siz[tr[p][c]],p=tr[p][!c];
	}
	return ans;
}
priority_queue< node > qu;
signed main(){
//	fre();
	n=read(),k=read()<<1;
	for(int i=1;i<=n;i++) a[i]=read(),s[i]=s[i-1]^a[i];
	for(int i=0;i<=n;i++) insert(s[i]);
	for(int i=0;i<=n;i++) qu.push(node{i,1,query(s[i],1)});
	ll ans=0;
	while(k--){
		auto zzz=qu.top(); qu.pop();
		ans+=zzz.w;
		if(zzz.k<n) qu.push(node{zzz.id,zzz.k+1,query(s[zzz.id],zzz.k+1)});
	}
	cout<<(ans>>1);
	return 0;
}
相关推荐
古城小栈2 小时前
为啥说:训练用BF16,推理用FP16
人工智能·算法·机器学习
KaMeidebaby2 小时前
卡梅德生物技术快报|蛋白 N 端测序在重组贻贝融合蛋白表征中的应用,解决原核表达序列偏移工艺难题
前端·人工智能·物联网·算法·百度
Byron__3 小时前
AI学习_06_短期记忆与长期记忆
人工智能·python·学习
浆果02073 小时前
NanoTrack C++ — RK3588 实时目标跟踪
c++·目标跟踪·rk3588
Turbo正则3 小时前
群论在AI中的应用概述
人工智能·算法·抽象代数
ysa0510303 小时前
【并查集】判环
c++·笔记·算法
持力行4 小时前
C/C++ 中的 char*:它标识数组吗?为什么能用下标访问?
c语言·c++
Jerry4 小时前
KeetCode 44. 开发商购买土地
算法
试剂界的爱马仕4 小时前
Anti-mouse PD-1 mAb (Clone RMP1-14) 与 Axitinib 小鼠实验使用方案整理汇总
大数据·人工智能·深度学习·学习
Jerry4 小时前
KeetCode 58. 区间和
算法