CF1100F题解

\(CF1100F\)\(Ivan\) \(and\) \(Burgers\)

题意:静态序列查询一个区间中选取任意个数的最大异或和,\((n\le 10^6)\)

\(sol\) :考虑离线做,把询问按 \(r\) 从小到大排序,每次 \(r\) 右移时把新框进来的数加入线性基中,同时记录线性基每一位在序列中的位置,贪心的考虑显然位置越靠后越优,查询时处理当前线性基中位置大于等于 \(l\) 的即可

\(code\) :

#include<bits/stdc++.h>
using namespace std;
const int N=5e5+5;
inline int rd()
{
	char c;int f=1;
	while(!isdigit(c=getchar())){if(c=='-') f=-1;}
	int x=c^48;
	while(isdigit(c=getchar())){x=x*10+(c^48);}
	return x*f;
}
int n,m,l,r,a[N],w[100],pos[100],ans[N];
struct node{int l,r,id;}q[N];
int cmp(node x,node y){return x.r<y.r;}
void add(int x,int l)
{
	for(int i=20;~i;i--)
		if(x>>i&1)
		{
	        if(!w[i])
			{
	            w[i]=x,pos[i]=l;
	            break;
	        }
	        if(pos[i]<l) swap(x,w[i]),swap(pos[i],l);
	        x^=w[i];
	    }
}
int query(int l)
{
	int ans=0;
	for(int i=20;~i;i--)
		if(pos[i]>=l) ans=max(ans^w[i],ans);
	return ans;
}
int main()
{
	n=rd();
	for(int i=1;i<=n;i++) a[i]=rd();
	m=rd();
	for(int i=1;i<=m;i++) q[i]={rd(),rd(),i};
	sort(q+1,q+m+1,cmp);int s=1;
	for(int i=1;i<=m;i++)
	{
		while(s<=q[i].r) add(a[s],s),s++;
		ans[q[i].id]=query(q[i].l);
	}
	for(int i=1;i<=m;i++) printf("%d\n",ans[i]);
	return 0;
}
posted @ 2024-12-18 20:23  Re_Star  阅读(74)  评论(1)    收藏  举报