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;
}
相关推荐
wayz111 小时前
Momentum:TSI(真实强度指数)技术指标详解
算法·金融·数据分析·量化交易·特征工程
Queenie_Charlie1 小时前
哈夫曼树
数据结构·c++·哈夫曼树
编程圈子1 小时前
电机驱动开发学习2. 直流无刷电机工作原理
驱动开发·学习
MartinYeung52 小时前
[论文学习]大型语言模型(LLM)安全与隐私-基于善、恶、丑的深度分析
学习·安全·语言模型
万事大吉CC2 小时前
Python 笔试输入模板总结
python·算法
什仙2 小时前
Mathcad Prime 的教程资料
学习·工具
lihao lihao2 小时前
Linux信号
开发语言·c++·算法
大白话_NOI2 小时前
【洛谷 P2249】查找(深基 13. 例 1)+ 详细分析
c++·算法
吠品2 小时前
C++实现m行n列带边框的长方形输出
算法