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;
}
相关推荐
鸿芯微控科技11 分钟前
MFC关断后还有流量怎么办?零流量、阀门泄漏、压差与Python分析
c++·python·mfc·质量流量控制器·关断泄漏·零流量测试
青山是哪个青山8 小时前
LangChain 学习笔记(四):Message 与提示词模板
笔记·学习·langchain
大明者省10 小时前
WSL2 Ubuntu22.04 GPU训练环境配置指南
人工智能·算法·计算机视觉
hsjiasb10 小时前
FreeRTOS学习(二十六)——动态内存管理heap_1到heap_5
stm32·单片机·学习·学习笔记·freertos
崇子嵘10 小时前
基于zynqMP15eg的linux驱动学习
学习
白狐_79811 小时前
408数据结构第8章:排序②——性质对比秒杀、场景选择与外部排序
java·数据结构·算法
zander25812 小时前
LeetCode 84:柱状图中的最大矩形——单调栈如何确定左右边界
java·数据结构·算法
ShineWinsu12 小时前
对于C++:C++11中lambda、function、bind的解析
c++·面试·笔试·开发·lambda·bind·function
知识分享小能手12 小时前
线性代数学习教程,从入门到精通,向量组的线性相关性 — 完整知识点梳理(7)
学习·线性代数·机器学习
码匠许师傅12 小时前
【C++ 面试真题】聊聊 C++ 的拷贝构造与拷贝赋值
java·c++·面试