codeforces 1100F Ivan and Burgers 线性基 离线

题目传送门

题意:

  给出 n 个数,q次区间查询,每次查询,让你选择任意个下标为 [ l , r ] 区间内的任意数,使这些数异或起来最大,输出最大值。

思路:离线加线性基。

线性基学习博客1

线性基学习博客2

对于此题,先把区间按照 r 从小到大排序,然后依次处理这些区间,每次插入线性基时,优先保留下标比较大的线性基。查询时,只异或上下标大于 l 的值。

记住异或的符号的优先级很低,所以  if( res^p[i] > res )这样的代码是会wa死的,要注意(这道题这么写,样例都过不了)

#include<bits/stdc++.h>
#define clr(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long ll;
const int maxn=5e5+10;
int a[maxn],q,n,p[30],pos[30],ans[maxn];
struct node{
    int l,r,id;
    friend bool operator<(const node &a,const node &b)
    {
        return a.r<b.r;
    }
}op[maxn];
void init(){
    clr(p,0);
}
void add(int val,int id){
    for(int i=20;i>=0;i--)
    {
        if(val&(1<<i))
        {
            if(!p[i]){
                p[i]=val,pos[i]=id;
                break;
            }
            if(pos[i]<id){
                swap(pos[i],id),swap(val,p[i]);
            }
            val^=p[i];
        }
    }
}
int query(int l)
{
    int res=0;
    for(int i=20;i>=0;i--)
    {
        if(pos[i]>=l)
        {
            if((res^p[i])>res)
            {
                res=res^p[i];
            }
        }
    }
    return res;
}
int main(){
    while(cin>>n)
    {
        init();
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
        }
        cin>>q;
        for(int i=1;i<=q;i++)
        {
            scanf("%d%d",&op[i].l,&op[i].r);
            op[i].id=i;
        }
        sort(op+1,op+1+q);
        int l=1;
        for(int i=1;i<=q;i++)
        {
            while(l<=op[i].r&&l<=n)
            {
                add(a[l],l);
                l++;
            }
            ans[op[i].id]=query(op[i].l);
        }
        for(int i=1;i<=q;i++)
        {
            printf("%d\n",ans[i]);
        }
    }
}

原文地址:https://www.cnblogs.com/mountaink/p/10348254.html

时间: 2024-08-30 08:05:42

codeforces 1100F Ivan and Burgers 线性基 离线的相关文章

CodeForces 1100F Ivan and Burgers

CodeForces题面 Time limit 3000 ms Memory limit 262144 kB Source Codeforces Round #532 (Div. 2) Tags data structures divide and conquer greedy math *2600 Editorial Announcement #1 (en) Announcement #2 (ru) Tutorial #1 (en) Tutorial #2 (ru) Tutorial #3 (

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

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

F. Ivan and Burgers(线性基,离线)

题目链接:http://codeforces.com/contest/1100/problem/F 题目大意:首先输入n,代表当前有n个数,然后再输入m,代表m次询问,每一次询问是询问区间[l,r],这段区间内的数的最大异或值. 具体思路:贪心,我们按照右边界的大小进行排序,小的在上面,大的往下安排,然后每一次我们寻找1--> r区间内的线性基,如果当前的线性基能往后移动,我们就选取后面的这个线性基(因为我们对输入的数据进行了排序,后面的r肯定是大的,所以我们将选取的线性基尽量的往后安排肯定是没

Codeforces 1100F(线性基+贪心)

题目链接 题意 给定序列,$q(1\leq q \leq 100000) $次询问,每次查询给定区间内的最大异或子集. 思路 涉及到最大异或子集肯定从线性基角度入手.将询问按右端点排序后离线处理询问,对线性基的每一位贪心的保留靠后的. 代码 #include <bits/stdc++.h> #define DBG(x) cerr << #x << " = " << x << endl; using namespace std;

【CF1100F】Ivan and Burgers(线性基,分治)

题意:给定n个数,每个数为c[i],有q个询问,每次询问从第l个到第r个数字的最大xor和 n,q<=5e5,c[i]<=1e6,时限3s 思路:直接线段树维护区间线性基是3个log 做法1:因为不是强制在线把询问分治能降到2个log 1 #include<bits/stdc++.h> 2 #include<cstdio> 3 #include<cstring> 4 #include<string> 5 #include<cmath>

Codeforces 724 G Xor-matic Number of the Graph 线性基+DFS

G. Xor-matic Number of the Graph http://codeforces.com/problemset/problem/724/G 题意:给你一张无向图.定义一个无序三元组(u,v,s)表示u到v的(不一定为简单路径)路径上xor值为s.求出这张无向图所有不重复三元组的s之和.1≤n≤10^5,1≤m≤2*10^5. 想法: 如果做过[Wc2011 xor]这道题目(题解),那么问题变得简单起来了. ①假设我们钦定一个(u,v),设任意一条u->v的路径xor值为X,

CodeForces 587 E.Duff as a Queen 线段树动态维护区间线性基

https://codeforces.com/contest/587/problem/E 一个序列, 1区间异或操作 2查询区间子集异或种类数 题解 解题思路大同小异,都是利用异或的性质进行转化,std和很多网友用的都是差分的思想,用两棵线段树 第一棵维护差分序列上的线性基,第二棵维护原序列的异或区间和,两者同时进行修改 考虑两个序列 $(a,b)(d,e)$,按照std的想法,应该是维护$(0 \^ a,a \^ b)(0 \^ d,d \^ e)$ 然后合并首尾变成$(0 \^ a,a \^

Codeforces 1163E Magical Permutation [线性基,构造]

codeforces 思路 我顺着图论的标签点进去的,却没想到-- 可以发现排列内每一个数都是集合里的数异或出来的. 考虑答案的上界是多少.如果能用小于\(2^k\)的数构造出\([0,2^k-1]\)内所有的数,那么答案就对这个\(k\)取\(\max\).很显然这一定是上界. 考虑能不能构造出一组解.把\([1,2^k-1]\)的数拎出来插入线性基里得到一组极大线性无关组,那么显然它的\(size\)就是\(k\).由于它线性无关,所以任意选取一个子集得到的异或和都不会相同,所以考虑把\(0

Codeforces 895C Square Subsets(状压DP 或 异或线性基)

题目链接  Square Subsets 这是白书原题啊 先考虑状压DP的做法 2到70总共19个质数,所以考虑状态压缩. 因为数据范围是70,那么我们统计出2到70的每个数的个数然后从2考虑到70. 设dp[x][mask]为考虑到x这个数的时候,x这个数和之前的所有数中,选出某些数,他们的乘积分解质因数,所有的指数对2取模之后, 状态为mask的方案数. 然后就可以转移了……这个状压DP花了我好几个小时……真是弱啊 哦对最后还要特判1的情况. 每个1选或不选都可以,然后考虑只选1的情况,累加