zoukankan      html  css  js  c++  java
  • CodeForces

    题目

    传送门

    解法

    暴力用线段树维护,线性基合并是 (mathcal O(nlog nlog^2 c)) 的。

    考虑线性基计算最大值时从最高位向低位异或,如果第 (i) 位因此变成 (1) 就异或。

    首先按 (r) 排序,将 (1) 到当前 (r)(a_i) 加入线性基。令 (lim[i]) 为第 (i) 位为 (1) 的最大位置(注意这不一定是最初态)。

    先看看 Insert()

    void Insert(int x,int pos) {
        fep(i,20,0) 
            if((x>>i)&1) {
                if(!d[i]) {d[i]=x,lim[i]=pos; break;}
                if(pos>lim[i]) swap(pos,lim[i]),swap(x,d[i]);
                x^=d[i];
            }
    }
    

    我们将位置大的优先选择。而且不会出现 (a_x) 被位置小于自己的数 (a_y) 异或导致 (a_x ext{xor} a_y) 存在必须保证取到位置 (y) 而不是传进去的参数 (x)

    那么最后的线性基异或和最大值异或的条件就多了一个:传进去的 (l)(左边界)小于等于 (lim[i])

    这道题还可以离线做,只要将 (r) 全插进去就行了,时间复杂度 (mathcal O(nlog n))

    可以离线与分治。

    二分数组下标,求出 (mid) 开始的后缀线性基与前缀线性基。对于跨过 (mid) 的询问,将其对应的前缀与后缀合并起来求得答案,其它的询问递归处理。

    每个询问只会合并一次,故时间复杂度 (mathcal O(qlog^2 c))

    对于分治部分,有一个 ( ext{OI Wiki}) 的主定理:

    此题 (a=b=2,k=1),故时间复杂度 (mathcal O(nlog^2 n))

    总时间复杂度 (mathcal O(nlog^2 n+qlog^2 c))

    代码

    #include <cstdio>
    
    #define rep(i,_l,_r) for(register signed i=(_l),_end=(_r);i<=_end;++i)
    #define fep(i,_l,_r) for(register signed i=(_l),_end=(_r);i>=_end;--i)
    #define erep(i,u) for(signed i=head[u],v=to[i];i;i=nxt[i],v=to[i])
    #define efep(i,u) for(signed i=Head[u],v=to[i];i;i=nxt[i],v=to[i])
    #define print(x,y) write(x),putchar(y)
    
    template <class T> inline T read(const T sample) {
        T x=0; int f=1; char s;
        while((s=getchar())>'9'||s<'0') if(s=='-') f=-1;
        while(s>='0'&&s<='9') x=(x<<1)+(x<<3)+(s^48),s=getchar();
        return x*f;
    }
    template <class T> inline void write(const T x) {
        if(x<0) return (void) (putchar('-'),write(-x));
        if(x>9) write(x/10);
        putchar(x%10^48);
    }
    template <class T> inline T Max(const T x,const T y) {if(x>y) return x; return y;}
    template <class T> inline T Min(const T x,const T y) {if(x<y) return x; return y;}
    template <class T> inline T fab(const T x) {return x>0?x:-x;}
    template <class T> inline T gcd(const T x,const T y) {return y?gcd(y,x%y):x;}
    template <class T> inline T lcm(const T x,const T y) {return x/gcd(x,y)*y;}
    template <class T> inline T Swap(T &x,T &y) {x^=y^=x^=y;}
    
    #include <iostream>
    #include <algorithm>
    using namespace std;
    
    const int maxn=5e5+5;
    
    int n,a[maxn],q,ans[maxn],d[50],lim[50];
    struct node {
    	int l,r,id;
    	
    	bool operator < (const node t) {
    		return r<t.r;
    	}
    } s[maxn];
    
    void Insert(int x,int pos) {
    	fep(i,20,0) 
    		if((x>>i)&1) {
    			if(!d[i]) {d[i]=x,lim[i]=pos; break;}
    			if(pos>lim[i]) swap(pos,lim[i]),swap(x,d[i]);
    			x^=d[i];
    		}
    }
    
    int calc(int l) {
    	int ret=0;
    	fep(i,20,0)
    		if(l<=lim[i] && ret<(d[i]^ret)) ret^=d[i];
    	return ret;
    }
    
    int main() {
    	n=read(9);
    	rep(i,1,n) a[i]=read(9);
    	q=read(9);
    	rep(i,1,q) s[i].id=i,s[i].l=read(9),s[i].r=read(9);
    	sort(s+1,s+q+1);
    	int Pointer=0;
    	rep(i,1,q) {
    		while(Pointer<s[i].r) {
    			++Pointer;
    			Insert(a[Pointer],Pointer);
    		}
    		ans[s[i].id]=calc(s[i].l);
    	}
    	rep(i,1,q) print(ans[i],'
    ');
    	return 0;
    }
    
  • 相关阅读:
    在线考试————随机出题
    HTTP协议
    团队
    做作业
    图书馆管理说明书性能
    关于敏捷开发的学习
    运行环境
    图书馆管理系统说明书
    性能(2)
    作业
  • 原文地址:https://www.cnblogs.com/AWhiteWall/p/14407606.html
Copyright © 2011-2022 走看看