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 天前
给AI一张“业务概念地图“:本体如何从哲学走向企业智能
大数据·人工智能·经验分享·笔记·学习·学习方法·政务
倒头就睡的小比特2 天前
算法竞赛C++常用的STL
c++·算法
weilx12342 天前
C++笔记-文件IO-<fcntl.h>
c++
小羊没烦恼!2 天前
初探性能优化——2个月到4小时的性能提升
java·开发语言·windows·算法·c#
XiHongShi20162 天前
STM32F407 RTC定时器例程,建议保存
stm32·单片机·学习
爱吃苹果的日记本2 天前
离散数学第六课
学习·离散数学
猎头南楼2 天前
知识社区推荐系统实践:新用户冷启动与长短期兴趣建模的挑战 资深推荐算法工程师
人工智能·深度学习·算法·机器学习
Smileyqp沛沛2 天前
前端?C++ ?较大差异基础罗列
c++·基础·前端转c++
C语言小火车2 天前
C/C++ 为什么需要编译器?
开发语言·c++