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;
}
相关推荐
Persistent的粽子!38 分钟前
C++:类与对象(二)
开发语言·c++
Omics Pro1 小时前
Arc研究所Cell|全新虚拟细胞官方基准评测框架
大数据·人工智能·深度学习·算法·机器学习
小雪崩1 小时前
嵌入式学习 day39:TCP并发服务器模型
linux·服务器·c语言·网络·学习·tcp/ip
蒸蒸yyyyzwd1 小时前
cpp 选手备战秋招学习笔记 day23
c++·求职招聘
.YM.Z1 小时前
C++ STL 容器深度剖析:vector 与 list 的模拟实现及对比
开发语言·c++·vector·list
知识分享小能手1 小时前
深度学习学习教程,从入门到精通,概率与信息论 — 知识点详解(3)
人工智能·深度学习·学习·数据挖掘·概率论
Wendy不吃榴莲1 小时前
# AI短剧教程 - 《后西游记》开播后,AI影视为什么更考验“连续讲故事”?
人工智能·笔记·学习·ai·视频
Agudamu11612 小时前
B站学习视频怎么变笔记:用 Ai好记 + Obsidian 搭建个人知识库的完整教程
人工智能·笔记·学习·音视频
kkkkkkkkkk_Z2 小时前
学嵌入式和Linux应用编程|学习日记:计算机网络基础
linux·学习·计算机网络
麦田里的粮仓2 小时前
图形设计工具箱(免费开源)
学习