P5283 [十二省联考 2019] 异或粽子

做法跟 P2048 [NOI2010] 超级钢琴 中题解做法基本一样。

现在就是要找到右端点 \(r\in[L,R]\) 使得 \(sum_r\oplus sum_{l-1}\) 最大,其中 \(sum\) 为异或前缀和。容易可持久化 trie 实现。

Takanshi Rikka
#include<bits/stdc++.h>
using namespace std;
#define fin(x) freopen(#x".in","r",stdin)
#define fout(x) freopen(#x".out","w",stdout)
#define fr(x) fin(x),fout(x);
#define Fr(x,y) fin(x),fout(y)
#define INPUT(_1,_2,FILE,...) FILE
#define IO(...) INPUT(__VA_ARGS__,Fr,fr)(__VA_ARGS__)
#define mp make_pair
#define pii pair<int,int>
#define fi first
#define se second
#define pb push_back
#define il inline
#define cfast ios::sync_with_stdio(false);cin.tie(0),cout.tie(0)
#define ll long long
#define ull unsigned long long
#define intz(x,y) memset((x),(y),sizeof((x)))
inline void cmx(auto &x,ll y){if(y>x)x=y;}
inline void cmn(auto &x,ll y){if(y<x)x=y;}
inline int max(vector<int>w){int res=-1e9;for(int i:w)cmx(res,i);return res;}
#define pcount(x) __builtin_popcount(x)
const int N=5e5+5;
#define int ll
int a[N],s[N],tot,rt[N],t[N*35],son[N*35][2];
struct state{
	int l,L,R;ll x,sum;
	il friend bool operator<(state x,state y){
		return x.sum<y.sum;
	}
};priority_queue<state>dl;
il void cpy(int x,int y){
	son[x][0]=son[y][0],
	son[x][1]=son[y][1],
	t[x]=t[y];
}
il void add(int id,int x){
	int u=rt[id]=++tot,idx=rt[id-1];
	cpy(tot,idx);
	for(int i=32;~i;i--){
		int p=(x>>i)&1;
		son[u][p]=++tot;
		cpy(tot,son[idx][p]);
		u=son[u][p],idx=son[idx][p],++t[u];
	}
}
il int query(int l,int r,int x){
	int id=rt[r],idx=rt[l-1],res=0;
	for(int i=32;~i;i--){
		int p=(x>>i)&1;
		if(t[son[id][!p]]-t[son[idx][!p]])
			 id=son[id][!p],idx=son[idx][!p],res+=(!p)*(1ll<<i);
		else id=son[id][p],idx=son[idx][p],res+=p*(1ll<<i);
	}
	return res;
}
map<ll,set<int> >pos;
void UesugiErii(){
	int n,k;cin>>n>>k;
	for(int i=1;i<=n;i++)
		cin>>a[i],s[i]=s[i-1]^a[i],add(i,s[i]),pos[s[i]].insert(i);
	for(int i=1;i<=n;i++){
		int tmp=query(i,n,s[i-1]);
		// cerr<<i<<' '<<tmp<<' '<<(tmp^s[i-1])<<'\n';
		dl.push({i,i,n,tmp,tmp^s[i-1]});
	}
	int ans=0;
	while(!dl.empty()&&(k--)){
		state u=dl.top();dl.pop();
		ans+=u.sum;
		int p=*pos[u.x].lower_bound(u.L);
		if(p-1>=u.L){
			int tmp=query(u.L,p-1,s[u.l-1]);
			dl.push(state{u.l,u.L,p-1,tmp,tmp^s[u.l-1]});
		}
		if(p+1<=u.R){
			int tmp=query(p+1,u.R,s[u.l-1]);
			dl.push(state{u.l,p+1,u.R,tmp,tmp^s[u.l-1]});
		}
	}
	cout<<ans;
}
signed main(){
	//IO();
	cfast;
	int _=1;//cin>>_;
	for(;_;_--)UesugiErii();
	return 0;
}
posted @ 2026-01-14 21:55  Uesugi1  阅读(3)  评论(0)    收藏  举报