Codeforces - Ivan and Burgers
程序员文章站
2022-05-27 20:26:48
...
题目链接:Codeforces - Ivan and Burgers
读题之后发现,比较显然的做法就是线段树维护线性基。(不过复杂度过高,一直没卡过去)。
我们可以尝试离线的做法、先按照右端点排序。
一次插入线性基当中,怎么保证当前对答案异或的时候,这个基底是存在于[l,r]当中的呢?我们每次插入线性基的时候记录一个时间戳即可。如果当前的时间戳大于等于L,就可以异或。
因为我们是从前往后面扫,所以时间戳每次选最大的更新。
卡常失败的代码:
#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include<bits/stdc++.h>
//#define int long long
using namespace std;
const int N=5e5+10;
int n,c[N],q;
char *fs,*ft,buf[1<<20];
#define gc() (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<20,stdin),fs==ft))?0:*fs++;
inline int read(){
int x=0,f=1; char ch=gc();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=gc();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=gc();}
return x*f;
}
struct lb{
int d[30];
inline void insert(int x){
for(int i=20;i>=0;i--) if(x>>i&1){
if(d[i]) x^=d[i];
else{d[i]=x; return ;}
}
}
inline void insert(lb &x){
for(int i=20;i>=0;i--) if(x.d[i]) insert(x.d[i]);
}
}t[N<<2],res;
void change(int p,int l,int r,int x,int v){
t[p].insert(v);
if(l==r) return ; int mid=l+r>>1;
if(x<=mid) change(p<<1,l,mid,x,v);
else change(p<<1|1,mid+1,r,x,v);
}
void ask(int p,int l,int r,int ql,int qr){
if(l==ql&&r==qr) return res.insert(t[p]),void();
int mid=l+r>>1;
if(qr<=mid) ask(p<<1,l,mid,ql,qr);
else if(ql>mid) ask(p<<1|1,mid+1,r,ql,qr);
else ask(p<<1,l,mid,ql,mid),ask(p<<1|1,mid+1,r,mid+1,qr);
}
inline int calc(){
int s=0;
for(int i=20;i>=0;i--) if((s^res.d[i])>s) s^=res.d[i];
return s;
}
signed main(){
n=read();
for(int i=1;i<=n;i++) c[i]=read(),change(1,1,n,i,c[i]);
q=read();
for(int i=1,l,r;i<=q;i++){
l=read(),r=read(); memset(res.d,0,sizeof res.d);
ask(1,1,n,l,r); printf("%d\n",calc());
}
return 0;
}
AC代码:
#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include<bits/stdc++.h>
//#define int long long
using namespace std;
const int N=5e5+10;
int n,d[25],dfn[25],c[N],q,res[N];
struct node{int l,r,id;}t[N];
char *fs,*ft,buf[1<<20];
#define gc() (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<20,stdin),fs==ft))?0:*fs++;
inline int read(){
int x=0,f=1; char ch=gc();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=gc();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=gc();}
return x*f;
}
int cmp(node a,node b){return a.r<b.r;}
inline void insert(int x,int id){
for(int i=20;i>=0;i--) if(x>>i&1){
if(!d[i]){d[i]=x; dfn[i]=id; return;}
if(dfn[i]<id) swap(d[i],x),swap(dfn[i],id);
x^=d[i];
}
}
inline int ask(int id){
int res=0;
for(int i=20;i>=0;i--) if(dfn[i]>=id&&(res^d[i])>res) res^=d[i];
return res;
}
signed main(){
n=read();
for(int i=1;i<=n;i++) c[i]=read();
q=read();
for(int i=1;i<=q;i++) t[i].l=read(),t[i].r=read(),t[i].id=i;
sort(t+1,t+1+q,cmp); int ed=1;
for(int i=1;i<=q;i++){
while(ed<=t[i].r) insert(c[ed],ed),ed++;
res[t[i].id]=ask(t[i].l);
}
for(int i=1;i<=q;i++) printf("%d\n",res[i]);
return 0;
}
推荐阅读
-
『ACM C++』 Codeforces | 1003C - Intense Heat
-
Codeforces 939A题,B题(水题)
-
CodeForces 29D Ant on the Tree
-
Codeforces Global Round 9-C. Element Extermination
-
codeforces 712B Memory and Trident
-
CodeForces 962D Merge Equals
-
Codeforces Round #655 (Div. 2) A. Omkar and Completion
-
CodeForces 1326E - Bombs
-
CodeForces 612E Square Root of Permutation
-
codeforces736D. Permutations(线性代数)