如果没有修改,这个题就是个线性基板子题对吧。

再看加上修改之后怎么整。

我们发现,对于任意一种已经确定数字的情况,只要线性基建好了,答案可以搞出来。

那么问题就是怎么动态维护线性基。

啥?动态维护??不存在的!我才不告诉你我不会写那玩意

因为只有删除操作,所以顺序颠倒就是一个一个加入数字。

也就是离线然后一个一个插入线性基。

这样就搞定了,复杂度也就

再看那个区间怎么整。

由于区间具有连续性,所以我们可以考虑用并查集来搞事。

每次假如一个数,如果这个数左或者右边有存在的区间,那就合并并查集,并且暴力合并线性基。

答案就是前一个询问的答案与当前数字对应答案取最大值。

附代码:

#include<iostream>
#include<algorithm>
#include<cstdio>
#define MAXN 100010
#define MAXM 64
using namespace std;
int n,pos[MAXN],fa[MAXN];
long long val[MAXN],ans[MAXN];
struct Linear_Basis{
    long long base[MAXM];
    bool flag_zero;
    void init(){
        flag_zero=false;
        for(int i=0;i<=62;i++)base[i]=0;
    }
    void insert(long long x){
        for(int i=62;~i;i--)if(x&(1LL<<i)){
            if(!base[i]){base[i]=x;return;}
            else x^=base[i];
        }
        flag_zero=true;
    }
    friend Linear_Basis operator +(const Linear_Basis u,const Linear_Basis v){
        Linear_Basis ret;
        ret.init();
        for(int i=62;~i;i--){
            if(u.base[i])ret.insert(u.base[i]);
            if(v.base[i])ret.insert(v.base[i]);
        }
        ret.flag_zero=u.flag_zero|v.flag_zero;
        return ret;
    }
    long long query_max(long long s){
        for(int i=62;~i;i--)s=max(s,s^base[i]);
        return s;
    }
}a[MAXN];
char tp[100000],*p1=tp,*p2=tp;
inline char get_char(){
    return p1==p2&&(p2=(p1=tp)+fread(tp,1,100000,stdin),p1==p2)?EOF:*p1++;
}
inline int read(){
    int date=0,w=1;char c=0;
    while(c<'0'||c>'9'){if(c=='-')w=-1;c=get_char();}
    while(c>='0'&&c<='9'){date=date*10+c-'0';c=get_char();}
    return date*w;
}
int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
void uniun(int x,int y){
    x=find(x);y=find(y);
    if(x!=y){
        fa[y]=x;
        a[x]=a[x]+a[y];
    }
}
void work(){
    for(int i=n;i>=1;i--){
        fa[pos[i]]=pos[i];
        a[pos[i]].init();
        a[pos[i]].insert(val[pos[i]]);
        if(fa[pos[i]+1])uniun(pos[i],pos[i]+1);
        if(fa[pos[i]-1])uniun(pos[i],pos[i]-1);
        ans[i]=max(ans[i+1],a[pos[i]].query_max(0));
    }
    for(int i=1;i<=n;i++)printf("%lld\n",ans[i]);
}
void init(){
    n=read();
    for(int i=1;i<=n;i++)val[i]=read();
    for(int i=1;i<=n;i++){
        pos[i]=read();
        fa[i]=0;
    }
}
int main(){
    init();
    work();
    return 0;
}