线段树维护线性基并——17西安icpc a

#include<bits/stdc++.h>
using namespace std;
#define N 10005

int a[N],n,k,q;

struct LB{
    int b[35];
    LB(){memset(b,0,sizeof b);}
    int check(int x){
        for(int i=29;i>=0;i--)if(x>>i & 1){
            if(!b[i])return 0;
            x^=b[i];
        }
        return 1;
    }
    void insert(int x){
        for(int i=29;i>=0;i--)if(x>>i & 1){
            if(!b[i]){b[i]=x;return;}
            x^=b[i];
        }
    }
    int query_max(){
        int res=0;
        for(int i=29;i>=0;i--)
            res=max(res,res^b[i]);
        return res;
    }
};

#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
LB seg[N<<2];
LB merge(LB A,LB B){
    LB res;
    for(int i=29;i>=0;i--)
        res.b[i]=A.b[i];
    for(int i=29;i>=0;i--)
        if(B.b[i])
            res.insert(B.b[i]);
    return res;
}
void build(int l,int r,int rt){
    if(l==r){
        seg[rt].insert(a[l]);
        return;
    }
    int m=l+r>>1;
    build(lson);build(rson);
    seg[rt]=merge(seg[rt<<1],seg[rt<<1|1]);
}
LB query(int L,int R,int l,int r,int rt){
    if(L<=l && R>=r)return seg[rt];
    int m=l+r>>1;
    LB res;
    if(L<=m)res=merge(res,query(L,R,lson));
    if(R>m)res=merge(res,query(L,R,rson));
    return res;
}

void init(){
}

int main(){
    int t;cin>>t;while(t--){
        cin>>n>>q>>k;
        for(int i=1;i<=n;i++){
            /*k的存在会对求线性基最大值时的主元产生影响,所以预处理,a[i]只保留k没有的位*/
            scanf("%d",&a[i]);
            for(int j=0;j<30;j++)
                if((k>>j & 1) && (a[i]>>j & 1))
                    a[i]^=(1<<j);
        }

        build(1,n,1);
        while(q--){
            int L,R;scanf("%d%d",&L,&R);
            LB res=query(L,R,1,n,1);
            cout<<(res.query_max()|k)<<‘\n‘;
        }
    }
} 

原文地址:https://www.cnblogs.com/zsben991126/p/11629064.html

时间: 2024-10-09 01:39:07

线段树维护线性基并——17西安icpc a的相关文章

UVALive - 8512 线段树维护线性基(仅观赏)

题意:给定\(a[1...n]\),\(Q\)次询问求\(A[L...R]\)的异或组合再或上\(K\)的最大值 目前提交处于TLE状态,原因待查 #include<iostream> #include<algorithm> #include<cstdio> #include<cstring> #include<cstdlib> #include<cmath> #include<string> #include<ve

bzoj 4184: shallot (线段树维护线性基)

题面 \(solution:\) \(code:\) #include<iostream> #include<cstdio> #include<iomanip> #include<algorithm> #include<cstring> #include<cstdlib> #include<ctime> #include<cmath> #include<vector> #include<que

2017 ICPC西安区域赛 A - XOR (线段树并线性基)

链接:https://nanti.jisuanke.com/t/A1607 题面: Consider an array AA with n elements . Each of its element is A[i]A[i] (1 \le i \le n)(1≤i≤n) . Then gives two integers QQ, KK, and QQ queries follow . Each query , give you LL, RR, you can get ZZ by the foll

【线段树分治 线性基】luoguP3733 [HAOI2017]八纵八横

不知道为什么bzoj没有HAOI2017 题目描述 Anihc国有n个城市,这n个城市从1~n编号,1号城市为首都.城市间初始时有m条高速公路,每条高速公路都有一个非负整数的经济影响因子,每条高速公路的两端都是城市(可能两端是同一个城市),保证任意两个城市都可以通过高速公路互达. 国正在筹划“八纵八横”的高铁建设计划,计划要修建一些高速铁路,每条高速铁路两端也都是城市(可能两端是同一个城市),也都有一个非负整数的经济影响因子.国家还计划在“八纵八横”计划建成之后,将“一带一路”扩展为“一带_路一

Codeforces 938G 线段树分治 线性基 可撤销并查集

Codeforces 938G Shortest Path Queries 一张连通图,三种操作 1.给x和y之间加上边权为d的边,保证不会产生重边 2.删除x和y之间的边,保证此边之前存在 3.询问x到y的路径异或最小值 保证图在任意时刻连通 首先连通图路径异或相当于从x到y的任意一条路径再异或上若干个环得到的,只要在dfs过程中把非树边成的环丢到线性基里就好了,其他环一定可以通过这些环异或组合出来 有加边删边操作怎么做呢?线段树时间分治!注意到不能保证在线段树的任意一个节点图是连通的,需要用

HAOI2017 八纵八横——线段树分治+线性基

题目大意 给定一个图,每次加一些边,或者删掉一些后来加上去的边,定义一个环的价值为环上所有的边的异或和,重复走的边重复算.每次询问这个时刻图中的所有经过1号点的环的最大价值. 思路 首先考虑对于一个静态的图如何求解图中所有经过1号点的环的最大价值,发现这个经过1号点就是唬人的,图中任意一个环都可以经过1号点再走回来. 于是题目变成了求解图中环的最大价值,可以将图中所有的简单环给拎出来放到线性基里面求最大价值,不难发现这是对的. 然后题目转化为了如何求图中所有的简单环,一般我们可以直接对图dfs找

【bzoj4184】shallot 线段树+高斯消元动态维护线性基

题目描述 小苗去市场上买了一捆小葱苗,她突然一时兴起,于是她在每颗小葱苗上写上一个数字,然后把小葱叫过来玩游戏. 每个时刻她会给小葱一颗小葱苗或者是从小葱手里拿走一颗小葱苗,并且 让小葱从自己手中的小葱苗里选出一些小葱苗使得选出的小葱苗上的数字的异或和最大. 这种小问题对于小葱来说当然不在话下,但是他的身边没有电脑,于是他打电话给同为Oi选手的你,你能帮帮他吗? 你只需要输出最大的异或和即可,若小葱手中没有小葱苗则输出0. 输入 第一行一个正整数n表示总时间:第二行n个整数a1,a2...an,

2016shenyang-1002-HDU5893-List wants to travel-树链剖分+线段树维护不同区间段个数

肯定先无脑树链剖分,然后线段树维护一段区间不同个数,再维护一个左右端点的费用. 线段树更新,pushDown,pushUp的时候要注意考虑链接位置的费用是否相同 还有就是树链剖分操作的时候,维护上一个更新的位置的费用. 总之就是出现区间合并,就考虑总数是否要减一 好想不好写 //场上根本写不完啊 1 /*--------------------------------------------------------------------------------------*/ 2 3 #inc

CodeForces 343D 线段树维护dfs序

给定一棵树,初始时树为空 操作1,往某个结点注水,那么该结点的子树都注满了水 操作2,将某个结点的水放空,那么该结点的父亲的水也就放空了 操作3,询问某个点是否有水 我们将树进行dfs, 生成in[u], 访问结点u的时间戳,out[u],离开结点u的时间戳 每个结点的in值对应在线段树中的区间的一点 那么对于操作1, 只要将区间[in[u],out[u]] 的值都改为1, 但是如果区间[in[u],out[u]] 原先存在为0的点,那么父区间肯定是空的,这个操作不能 改变父区间的状态,所以需要