悬关,80,wa 18-21 T 1
查看原帖
悬关,80,wa 18-21 T 1
102457
personpeople楼主2024/9/17 13:41

每次确定区间右端点,寻找至多k个最大值插入优先队列

#include <bits/stdc++.h>
#define int long long
using namespace std;
using ll=long long;
const int N=5e5+9;
int n,k;
ll a,pre=0;
bool is;
priority_queue<ll,vector<ll>,greater<ll>>q;
ll read(){
	ll x=0;
	char c;
	c=getchar();
	while(!isdigit(c)){
		c=getchar();
	}
	while(isdigit(c)){
		x=(x<<3)+(x<<1)+(c^48);
		c=getchar();
	}
	return x;
}
struct trie{
	int nex[N<<6][2],cnt;
	trie(){
		memset(nex,0,sizeof(nex));
		cnt=0;
	}
	void insert(ll x){
		int p=0;
		for(int i=32;i>=0;i--){
			int j=x>>i&1;
			if(!nex[p][j])nex[p][j]=++cnt;
			p=nex[p][j];
		}
	}
	void dfs(ll x,ll p,ll num,ll temp){
		if(num<0){
			if(q.size()<k){
				q.push(temp);
			//	cout<<x<<' '<<temp<<'\n';	
			}
			else{
				if(temp>q.top()){
					q.pop();
					q.push(temp);
				//	cout<<x<<' '<<temp<<'\n';
				}
				else{
					is=0;
				}
			}
			return ;
		}
		if(!is)return ;
		int j=x>>num&1;
		if(nex[p][!j]){
			dfs(x,nex[p][!j],num-1,temp+(1ll<<num));
		}
		if(nex[p][j]){
			dfs(x,nex[p][j],num-1,temp);
		}
	}
};
trie t;
signed main(){
	n=read();
	k=read();
	t.insert(0);
	for(int i=1;i<=n;i++){
		a=read();
		pre^=a;
		is=1;
		t.dfs(pre,0,32,0);
		t.insert(pre);
	}
	ll final=0;
	while(q.size()){
		final+=q.top();
//		cout<<q.top()<<'\n';
		q.pop();
	}
	cout<<final<<'\n';
	return 0;
}
2024/9/17 13:41
加载中...