https://www.luogu.org/problem/P4839

 

题目: 有两个操作 1 a b  在a的位置添加b数值  (注意一个位置可以有多个值) 2 a b : 在 a到b的范围任取任意的数值相异或,结果最大。

 

分析:用线段树去维护这个操作合并线性基的操作;时间复杂度O(nlogmlogx)

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+10;
struct LB{
    int a[32];
    void add(int x){
        for(int i=31 ; i>=0 ; i--)
        {
            if(x&(1<<i)){
                if(!a[i]){
                    a[i]=x;
                    return ;
                }
                x^=a[i];
            }
        }
    }
    void add(LB &n){
        for(int i=31 ; i>=0 ; i--)
            if(n.a[i]) add(n.a[i]);
    }
}p[maxn],ans;
void update(int rt , int l , int r , int k , int x){
    p[rt].add(x);
    if(l==r) return;
    int mid=(l+r)>>1;
    if(k<=mid)
        update(rt<<1,l,mid,k,x);
    else
        update(rt<<1|1,mid+1,r,k,x);
}
void query(int rt , int l , int r , int ql , int qr){
    if(ql<=l&&qr>=r){
        ans.add(p[rt]);
        return ;
    }
    int mid=(l+r)>>1;
    if(qr<=mid) query(rt<<1,l,mid,ql,qr);
    else if(mid<ql) query(rt<<1|1,mid+1,r,ql,qr);
    else query(rt<<1,l,mid,ql,mid),query(rt<<1|1,mid+1,r,ql,qr);
}
int main(){
    int n,m;scanf("%d%d",&m,&n);
    for(int i=1 ; i<=m ; i++){
        int op,a,b;
        scanf("%d%d%d",&op,&a,&b);
        if(op==1) update(1,1,n,a,b);///在a位置插b
        else {
            memset(ans.a,0,sizeof(ans.a));
            query(1,1,n,a,b);
            int Max=0;
            for(int i=31 ; i>=0 ; i--)
                if((Max^(ans.a[i]))>Max)
                Max^=ans.a[i];
            printf("%d\n",Max);
        }
    }
    return 0;
}
View Code

相关文章:

  • 2021-08-23
  • 2021-09-30
  • 2022-02-08
  • 2022-02-07
  • 2021-06-26
  • 2021-10-15
  • 2021-08-15
  • 2022-12-23
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-06-10
  • 2021-09-24
  • 2021-06-07
  • 2021-11-19
相关资源
相似解决方案