[洛谷3812]【模板】线性基

题目大意:
  给你n个数,求这些数能异或出的数的最大值。

思路:
  线性基模板。
  b中的数满足对于每个b[i],最高位在第i位。
  构造方法就是对于每个数字,从高到低枚举每一个1,如果这一位对应的b[i]还没有,就把这个数作为b[i],如果有,就把这个数异或上b[i]。
  考虑两个数a,b,它们能异或出来的数为0,a,b,a xor b,如果把b换成a xor b,它们能异或出来的数还是0,a,b,a xor b。
  所以b能异或出来的值域和a能异或出来的值域相同。
  最后能异或出的最大值可以用类似贪心的思想。
  从高到低枚举每个数,如果和现在的ans异或起来比ans大那么就异或,不然就不管。
  这样就能优先保证更高的位出现在答案中,也就可以保证ans最大。

 1 #include<cstdio>
 2 #include<cctype>
 3 #include<algorithm>
 4 typedef long long int64;
 5 inline int64 getint() {
 6     register char ch;
 7     while(!isdigit(ch=getchar()));
 8     register int64 x=ch^‘0‘;
 9     while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^‘0‘);
10     return x;
11 }
12 const int N=51;
13 int64 b[N];
14 int main() {
15     const int n=getint();
16     for(register int i=0;i<n;i++) {
17         int64 x=getint();
18         for(register int i=N-1;~i;i--) {
19             if(!(x&(1ll<<i))) continue;
20             if(!b[i]) {
21                 b[i]=x;
22                 break;
23             } else {
24                 x^=b[i];
25             }
26         }
27     }
28     int64 ans=0;
29     for(register int i=N-1;~i;i--) {
30         ans=std::max(ans,ans^b[i]);
31     }
32     printf("%lld\n",ans);
33     return 0;
34 }
时间: 2024-10-10 07:50:18

[洛谷3812]【模板】线性基的相关文章

【C++】最近公共祖先LCA(Tarjan离线算法)&amp;&amp; 洛谷P3379LCA模板

1.前言 首先我们介绍的算法是LCA问题中的离线算法-Tarjan算法,该算法采用DFS+并查集,再看此算法之前首先你得知道并查集(尽管我相信你如果知道这个的话肯定是知道并查集的),Tarjan算法的优点在于相对稳定,时间复杂度也比较居中,也很容易理解(个人认为). 2.思想 下面详细介绍一下Tarjan算法的思想: 1.任选一个点为根节点,从根节点开始. 2.遍历该点u所有子节点v,并标记这些子节点v已被访问过. 3.若是v还有子节点,返回2,否则下一步. 4.合并v到u上. 5.寻找与当前点

AC自动机(附洛谷P3769模板题)

首先,介绍一下AC自动机(Aho-Corasick automaton),是一种在一个文本串中寻找每一个已给出的模式串的高效算法. 在学习AC自动机之前,你需要先学习Trie树和KMP算法,因为AC自动机正式利用并结合了两者的思想. 说到实际的不同,其实AC自动机只是在Trie树上引入了一个类似KMP中next数组的东西叫做Fail指针. 对于每一个节点,Fail指针指向该节点所代表的字符串中,次长的.在Trie树中存在的后缀(因为最长的在Trie树种存在的后缀就是其本身)所代表的节点. 举例:

[P3812][模板]线性基

解题关键:求异或最大值.线性基模板题. 极大线性无关组的概念. 异或的值域相同. #include<cstdio> #include<cstring> #include<algorithm> #include<cstdlib> #include<iostream> #include<cmath> using namespace std; typedef long long ll; const int MAX_BASE=63; ll b

[算法模板]线性基

线性基 GavinZheng敲懒的... menci大佬的线性基博客 模板代码引自menci: struct LinearBasis { long long a[MAXL + 1]; LinearBasis() { std::fill(a, a + MAXL + 1, 0); } LinearBasis(long long *x, int n) { build(x, n); } void insert(long long t) { for (int j = MAXL; j >= 0; j--)

洛谷P3375 [模板]KMP字符串匹配

To 洛谷.3375 KMP字符串匹配 题目描述 如题,给出两个字符串s1和s2,其中s2为s1的子串,求出s2在s1中所有出现的位置. 为了减少骗分的情况,接下来还要输出子串的前缀数组next.如果你不知道这是什么意思也不要问,去百度搜[kmp算法]学习一下就知道了. 输入输出格式 输入格式: 第一行为一个字符串,即为s1(仅包含大写字母) 第二行为一个字符串,即为s2(仅包含大写字母) 输出格式: 若干行,每行包含一个整数,表示s2在s1中出现的位置 接下来1行,包括length(s2)个整

洛谷.3803.[模板]多项式乘法(FFT)

题目链接:洛谷.LOJ. FFT相关:快速傅里叶变换(FFT)详解.FFT总结.从多项式乘法到快速傅里叶变换. #include <cmath> #include <cctype> #include <cstdio> #include <algorithm> #define gc() getchar() const int N=1e6+5; const double PI=acos(-1); int n,m; struct Complex { double

洛谷.1919.[模板]A乘B Problem升级版(FFT)

题目链接:洛谷.BZOJ2179 //将乘数拆成 a0*10^n + a1*10^(n-1) + ... + a_n-1的形式 //可以发现多项式乘法就模拟了竖式乘法 所以用FFT即可 注意处理进位 //n位*n位最多就只有2n位了 //论putchar的速度..还是快的 #include <cmath> #include <cstdio> #include <cctype> #include <algorithm> #define gc() getchar

[模板]线性基

用途 处理关于子集的异或和的问题,比如子集异或和的最大值,或者能不能异或出某个数 原理 从一堆数中处理出一组线性无关(?)的数,使得这些数能异或出的数和原来能异或出的数相同 线性基中,以每个位置为最高位1的数(最多)只有一个,这样就保证了线性无关 做法 依次处理每个数,对于x,从大到小扫描它的每一位,当扫到第i位为1时: 若线性基中没有最高位为i的数,则把x插到线性基中,结束扫描 若有,则把x异或上那个数,继续做 这样做,如果一个数最终没有被插入线性基中,证明它已经能被线性基中的数表示 而插到线

洛谷 [P2483] [模板] k短路

人生中的第一道黑题... 其实就是k短路模板 #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <cstdlib> #include <queue> using namespace std; const int MAXN=400005; int init(){ int