Codeforces - Ivan and Burgers

題目鏈接: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;
}
發佈了617 篇原創文章 · 獲贊 242 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章