Skip to content

区间线性基(区间异或,区间查询) ​

cpp
int a[N];
struct Node{
    int l,r;
    LinearBasis lb;
} t[N<<2];
void build(int p,int l,int r){
    t[p]={l,r};
    if(l==r){
        t[p].lb.insert(a[l]);
        return;
    }
    int mid=l+r>>1;
    build(p<<1,l,mid);
    build(p<<1|1,mid+1,r);
    t[p].lb=t[p<<1].lb|t[p<<1|1].lb;
}
void modify(int p,int x,int val){
    if(t[p].l==t[p].r){
        t[p].lb.init();
        t[p].lb.insert(val);
        return;
    }
    int mid=t[p].l+t[p].r>>1;
    if(x<=mid)modify(p<<1,x,val);
    else modify(p<<1|1,x,val);
    t[p].lb=t[p<<1].lb|t[p<<1|1].lb;
}
LinearBasis query(int p,int l,int r){
    if(l<=t[p].l&&r>=t[p].r)return t[p].lb;
    int mid=t[p].l+t[p].r>>1;
    LinearBasis res;
    if(l<=mid)res=res|query(p<<1,l,r);
    if(r>mid)res=res|query(p<<1|1,l,r);
    return res;
}
template<typename T,typename F>
struct Fenwick{
    int n;
    vector<T> c;
    T identity;
    F op;
    Fenwick(){}
    Fenwick(int n_,T identity_=0){
        init(n,identity);
    }
    void init(int n_,T identity_=0){
        n=n_;
        c.assign(n,identity);
        identity=identity_;
    }
    void add(int x,T v,int rev=0){
        if(rev)x=n-x+1;
        for(;x<=n;x+=x&-x)c[x]=op(c[x],v);
    }
    T query(int x,int rev=0){
        if(rev)x=n-x+1;
        T res=identity;
        for(;x;x&=x-1)res=op(res,c[x]);
        return res;
    }
};
Fenwick<int,decltype([](const int &a,const int &b){return a^b;})> fw;
void solve(){
    int n,m;
    cin>>n>>m;
    fw.init(n+1,0);
    for(int i=1;i<=n;i++)cin>>a[i];
    for(int i=n;i>=1;i--)a[i]^=a[i-1],fw.add(i,a[i]);
    build(1,1,n);
    while(m--){
        int op,l,r,v;
        cin>>op>>l>>r>>v;
        if(op==1){
            fw.add(l,v);
            a[l]^=v;
            modify(1,l,a[l]);
            if(r<n){
                fw.add(r+1,v);
                a[r+1]^=v;
                modify(1,r+1,a[r+1]);
            }
        }
        else{
            int x=fw.query(l);
            if(l==r){
                cout<<max(v,x^v)<<"\n";
                continue;
            }
            auto res=query(1,l+1,r);
            res.insert(x);
            cout<<res.query_max(v)<<"\n";
        }
    }
}