zoukankan      html  css  js  c++  java
  • 「bzoj 4184: shallot」

    权限题

    线段树分治加线性基

    首先这个题要求删除线性基肯定是没法处理的

    于是我们套上一个线段树分治

    线段树分治就是一种能够避免删除的神仙操作

    我们发现询问是对一个时间的单点询问,而每一个数存在的时间却是一个区间

    我们求出来每个数的存在区间,每一个区间对应在线段树上并不会超过(logn)

    我们就把这些存活区间插入到线段树里去,标记永久化一下

    由于一个线性基也就是(logn)的空间,所以我们直接一路把线性基搞下来,中间把标记插入线性基就好了

    到叶子结点我们就可以处理询问了

    代码

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<vector>
    #define max(a,b) ((a)>(b)?(a):(b))
    #define min(a,b) ((a)<(b)?(a):(b))
    #define LL long long
    #define re register
    #define maxn 500005
    inline int read() {
        char c=getchar();int x=0,r=1;
        while(c<'0'||c>'9') {if(c=='-') r=-1;c=getchar();}
        while(c>='0'&&c<='9') x=(x<<3ll)+(x<<1ll)+c-48,c=getchar();return x*r;
    }
    struct Base {
        int lb[33];
        inline void ins(int x) {
            for(re int i=31;i>=0;--i) 
            if(x>>i&1) {
                if(!lb[i]) {lb[i]=x;return;}
                x^=lb[i];
            }
        }
        inline int query() {
            int ans=0;
            for(re int i=31;i>=0;--i) if((ans^lb[i])>ans) ans^=lb[i];
            return ans;
        }
    }A;
    std::vector<int> v[maxn*3];
    int n,m,sz,tot;
    int lst[maxn],nxt[maxn],L[maxn],R[maxn],val[maxn],ans[maxn],c[maxn],a[maxn];
    inline int find(int x) {
        int l=1,r=sz;
        while(l<=r) {
            int mid=l+r>>1;
            if(c[mid]==x) return mid;
            if(c[mid]<x) l=mid+1;else r=mid-1;
        }
        return 0;
    }
    void change(int l,int r,int x,int y,int val,int i) {
        if(x<=l&&y>=r) {v[i].push_back(val);return;}
        int mid=l+r>>1;
        if(x<=mid) change(l,mid,x,y,val,i<<1);
        if(y>=mid+1) change(mid+1,r,x,y,val,i<<1|1); 
    }
    void solve(int l,int r,int i,Base A) {
        for(re int j=0;j<v[i].size();j++) 
    		A.ins(v[i][j]);
    	if(l==r) {
    		ans[l]=A.query();
    		return;
    	}
    	int mid=l+r>>1;
    	solve(l,mid,i<<1,A);solve(mid+1,r,i<<1|1,A);
    }
    int main() {
        n=read();
        for(re int i=1;i<=n;i++) a[i]=read();
        for(re int i=1;i<=n;i++) c[i]=((a[i]>0)?a[i]:-1*a[i]);
        std::sort(c+1,c+n+1);sz=std::unique(c+1,c+n+1)-c-1;
        for(re int i=1;i<=n;i++) {
            int x=find((a[i]>0)?a[i]:-1*a[i]);
            if(a[i]>0) {
            	nxt[i]=lst[x],lst[x]=i;
    		}
            else {
                L[++tot]=lst[x];R[tot]=i-1;val[tot]=-1*a[i];
                lst[x]=nxt[lst[x]];
            }
        }
        for(re int i=1;i<=sz;i++) 
            while(lst[i]) L[++tot]=lst[i],R[tot]=n,val[tot]=c[i],lst[i]=nxt[lst[i]];
        for(re int i=1;i<=tot;i++) 
            change(1,n,L[i],R[i],val[i],1);
        solve(1,n,1,A);
        for(re int i=1;i<=n;i++) printf("%d
    ",ans[i]);
        return 0;
    }
    
  • 相关阅读:
    周末总结
    大数据开源框架技术汇总
    oracle迁移mysql总结
    梯度下降
    BFC的概念
    元素类型
    window10安装tensorflow
    学习使用git
    设计模式中的关系
    拟合圆
  • 原文地址:https://www.cnblogs.com/asuldb/p/10518183.html
Copyright © 2011-2022 走看看