【Codeforces 1100F】Ivan and Burgers | 持久化线性基、扫描线
作者:互联网
题目大意:
询问区间 [ L , R ] [L,R] [L,R]内子集异或第 k k k大
题目思路:
强制在线也可…
但是没有强制在线,直接离线+扫描线就行了
考虑将线性基可持久化,对于一个新来的数 x x x,在插入线性基时,可能会发生这些替换使得最后 x x x变为 y y y:
y = x ⊕ x 1 ⊕ x 2 ⊕ x 3 ⊕ x 4 ⊕ x 5 y = x⊕x_1⊕x_2⊕x_3⊕x_4⊕x_5 y=x⊕x1⊕x2⊕x3⊕x4⊕x5
那么考虑当 x ⊕ x 1 x⊕x_1 x⊕x1时,也就说此时 x x x是可以将 x 1 x_1 x1在线性基中主元的位置替换掉,所以看一下 x x x的位置是不是要比 x 1 x_1 x1的位置要大(因为向右维护),大就交换一下,这样一定保证当前线性基内是最靠右的集合。
仔细推一下,发现 p o s [ i ] pos[i] pos[i]代表的是 (异或 = b [ i ] b[i] b[i])的集合元素中出现最左的位置。
Code:
#pragma GCC optimize(3)
#include <bits/stdc++.h>
#include<stdio.h>
#include<queue>
#include<algorithm>
#include<string.h>
#include<iostream>
#define debug(x) cout<<#x<<":"<<x<<endl;
#define dl(x) printf("%lld\n",x);
#define di(x) printf("%d\n",x);
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
const ll INF= 1e18+7;
const ll maxn = 1e6+700;
const int M = 1e6+8;
const ll mod= 998244353;
const double eps = 1e-9;
const double PI = acos(-1);
template<typename T>inline void read(T &a){char c=getchar();T x=0,f=1;while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
while(isdigit(c)){x=(x<<1)+(x<<3)+c-'0';c=getchar();}a=f*x;}
ll n,m,p;
ll copa[maxn];
vector<pair<int,int>>v[maxn];
int b[maxn],pos[maxn],a[maxn];
void insert(int x,int id){
for(int i=21;i>=0;i--){
if(!(x>>i)&1) continue;
if(!b[i]){
b[i] = x;
pos[i] = id;
return ;
}
if(pos[i]<id){
swap(id,pos[i]);
swap(x,b[i]);
}
x^=b[i];
}
return ;
}
ll res[maxn];
int main(){
read(n);
for(int i=1;i<=n;i++) read(a[i]);
read(m);
for(int i=1;i<=m;i++){
int x,y;read(x);read(y);
v[y].push_back({x,i});
}
for(int i=1;i<=n;i++){
insert(a[i],i);
for(auto x:v[i]){
int idx = x.second,l = x.first;
ll ans = 0;
for(int k=21;k>=0;k--){
if(pos[k]>=l && (ans^b[k])>ans){
ans ^= b[k];
}
}
res[idx] = ans;
}
}
for(int i=1;i<=m;i++) di(res[i]);
return 0;
}
/***
***/
标签:int,Codeforces,pos,Burgers,maxn,扫描线,ans,read,include 来源: https://blog.csdn.net/qq_43857314/article/details/114948982