「HDU6579 Operation」 - 线性基

HDU 6579

tags:线性基,优化

题意

让你在区间 \([l,r]\) 中选若干个数,使得异或和最大
支持末尾加入,区间查询,强在

题解

可以暴力维护区间的线性基,但是会超时

考虑维护每个点的前缀线性基,线性基里将靠右的数字尽可能放高位,就是存一个额外存一个位置 p,表示这个位上的数的位置,从高位到低位扫,如果当前位置大于这个位上的位置那么交换,然后就得到了一个靠右的数字尽可能在高位的线性基

然后对于询问 \([l,r]\)\(r\) 的前缀线性基里找,只在位置大于等于 \(l\) 的位更新答案

#include<cstdio>
#include<algorithm>
#define int long long
#define rep(i,a,b) for(int i=(a);i<=(b);++i)
template<typename T>inline void rd(T&x){int fl=0,ch;while(ch=getchar(),ch<48||57<ch)fl^=!(ch^45);x=(ch&15);while(ch=getchar(),47<ch&&ch<58)x=x*10+(ch&15);if(fl)x=-x;}
template<typename T>inline void pt(T x){if(x<0)putchar('-'),x=-x;if(x>9)pt(x/10);putchar(x%10+48);}
template<typename T>inline void pt(T x,int ch){pt(x),putchar(ch);}
template<typename T>inline T max(const T&x,const T&y){return x<y?y:x;}
template<typename T>inline T min(const T&x,const T&y){return x<y?x:y;}
const int N=500005;
int T,n,m,a[N],b[N][31],p[N][31];
void ins(int*b,int*p,int x,int pos){
    for(int i=30;~i;--i)if(x>>i&1){
        if(!b[i]){
            b[i]=x;
            p[i]=pos;
            break;
        }else{
            if(pos>p[i]){
                std::swap(b[i],x);
                std::swap(p[i],pos);
            }
            x^=b[i];
        }
    }
}
int qry(int*b,int*p,int pos){
    int res=0;
    for(int i=30;~i;--i)if(p[i]>=pos&&(res^b[i])>res)res^=b[i];
    return res;
}
signed main(){
    rd(T);
    while(T--){
        int n,m;rd(n),rd(m);
        rep(i,1,n){
            rd(a[i]);
            memcpy(b[i],b[i-1],sizeof(b[i]));
            memcpy(p[i],p[i-1],sizeof(p[i]));
            ins(b[i],p[i],a[i],i);
        }
        int lst=0;
        while(m--){
            int op;rd(op);
            if(op==0){
                int l,r;rd(l),rd(r);
                l=(l^lst)%n+1,r=(r^lst)%n+1;
                if(r<l)l^=r^=l^=r;
                pt(lst=qry(b[r],p[r],l),'\n');
            }else{
                rd(a[++n]);a[n]^=lst; 
                memcpy(b[n],b[n-1],sizeof(b[n])); 
                memcpy(p[n],p[n-1],sizeof(p[n]));
                ins(b[n],p[n],a[n],n);
            }
        }
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/xay5421/p/11228086.html