P3812 【模板】線性基
不得不說,線性基是一個神奇的東西
它維護的東西與“異或”密切相關
題意:
給定n個整數(數字可能重複),求在這些數中選取任意個,使得他們的異或和最大。
當然,也可以最小,甚至,可以求任意異或和第k大!(哇,好niubi)
a[i]表示當前線性基內任意異或出來的數字中,最高位為i的任意一個數字。
從高位到低位列舉所有位數,如果x的第i位有值:如果a[i]不存在,則a[i]=x,並退出。
如果a[i]存在,令x^=a[i]。如果最後x變成了0,那麼說明x線上性基內。
inline bool insert(int x) { for(int i=nmr;i>=0;i--) { if(x&(1LL<<i)) { if(a[i]==0) { a[i]=x; break; } x^=a[i]; } } return x>0; }
從高位到低位掃描線性基。如果異或之後答案變大,就把這一位異或到答案。
inline int get_max() { int ans=0; for(int i=nmr;i>=0;i--) { if((ans^a[i])>ans) ans^=a[i]; } return ans; }
查詢最小值
從低位到高位掃描線性基。最低位上的線性基即為答案。
inline int get_min() { for(int i=0;i<=nmr;i++) if(a[i]>0) return a[i]; }
首先我們要改造一下線性基。我們把線性基改造成每一位相互獨立,意思就是對於第i位,
線性基上只有第i位可能是1。(其它位是1就不相互獨立了(互相異或不對了))具體如何改造,就是從高位向低位掃描,
對於第i位線性基a[i],對於j<i,如果a[i]的第j位是1,就讓a[j]異或上a[i]。
查詢的時候,將k進行二進位制拆分,對於的1位,就異或對應的線性基。
最終得到的答案是第k小值。
inline void rebuild() { cnt=0; for(int i=nmr;i>=0;i--) { for(int j=i-1;j>=0;j--) if(a[i]&(1LL<<j)) a[i]^=a[j]; } for(int i=0;i<=nmr;i++) if(a[i]) p[cnt++]=a[i]; } inline int query(int k) { int ans=0; if(k>=(1LL<<cnt)) return -1; for(int i=nmr;i>=0;i--) { if(k&(1LL<<i)) ans^=p[i]; } return ans; }
so
線性基碼量小,而且速度快(遇到異或問題可以想到線性基666)
基於本題:只要查詢最大值即可,這裡給出全程式碼
#include<cstdio> #include<iostream> #include<cstring> using namespace std; #define olinr return #define nmr 60 #define love_nmr 0 #define int long long int a[nmr]; int cnt; int n; int x; int p[nmr]; inline bool insert(int x) { for(int i=nmr;i>=0;i--) { if(x&(1LL<<i)) { if(a[i]==0) { a[i]=x; break; } x^=a[i]; } } return x>0; } inline int get_max() { int ans=0; for(int i=nmr;i>=0;i--) { if((ans^a[i])>ans) ans^=a[i]; } return ans; } inline int get_min() { for(int i=0;i<=nmr;i++) if(a[i]>0) return a[i]; } inline void rebuild() { cnt=0; for(int i=nmr;i>=0;i--) { for(int j=i-1;j>=0;j--) if(a[i]&(1LL<<j)) a[i]^=a[j]; } for(int i=0;i<=nmr;i++) if(a[i]) p[cnt++]=a[i]; } inline int query(int k) { int ans=0; if(k>=(1LL<<cnt)) return -1; for(int i=nmr;i>=0;i--) { if(k&(1LL<<i)) ans^=p[i]; } return ans; } signed main() { ios::sync_with_stdio(false); cin>>n; for(int i=1;i<=n;i++) { cin>>x; insert(x); } cout<<get_max(); olinr love_nmr; }
相關推薦
洛谷P3812 【模板】線性基
int clas ott style psu ont radi reg query 題目背景 這是一道模板題。 題目描述 給定n個整數(數字可能重復),求在這些數中選取任意個,使得他們的異或和最大。 輸入輸出格式 輸入格式: 第一行一個數n,表示元素個數
題解——洛谷P3812【模板】線性基
打了 () 運算優先級 運算 pac sca bre std 線性基 學了下線性基 使用好像並不復雜 打了板子 但是要註意位運算優先級 #include <cstdio> #include <algorithm> #include &
P3812 【模板】線性基
不得不說,線性基是一個神奇的東西 它維護的東西與“異或”密切相關 題意: 給定n個整數(數字可能重複),求在這些數中選取任意個,使得他們的異或和最大。 當然,也可以最小,甚至,可以求任意異或和第k大!(哇,好niubi) 做法:開一個數組a[MAXN],MAXN是數字最高位數。 a[i
【模板】線性基(洛谷P3812)
size for 最大 個數 cstring 異或 namespace 元素 線性 Description 給定\(n\)個整數(數字可能重復),求在這些數中選取任意個,使得他們的異或和最大。 Input 第一行一個數\(n\),表示元素個數 接下來一行\(n\
[洛谷3812]【模板】線性基
ons int() 方法 algorithm 每一個 枚舉 nbsp max tchar 題目大意: 給你n個數,求這些數能異或出的數的最大值。 思路: 線性基模板。 b中的數滿足對於每個b[i],最高位在第i位。 構造方法就是對於每個數字,從
【模板】線性基
ans clu using mem sizeof efi 輸入輸出 std ont 線性基就是一種可以維護異或和的東西,我還沒太懂它到底有什麽用,但是很好寫,而且思路也很清晰,所以板子還是很簡單的。 題幹: 題目背景 這是一道模板題。 題目描述 給定n個整
P3383 【模板】線性篩素數
... right else cst pre left 數據 ret col 題目描述 如題,給定一個範圍N,你需要處理M個某數字是否為質數的詢問(每個數字均在範圍1-N內) 輸入輸出格式 輸入格式: 第一行包含兩個正整數N、M,分別表示查詢的範圍和查詢
luogu_3383 【模板】線性篩素數
bre rime esp turn bit %d rim style clu 1 #include<bits/stdc++.h> 2 using namespace std; 3 int n,m,cnt,prime[10000010],noprime[1
【luogu 3383】【模板】線性篩素數
100% put pre esp log main col i++ 每一個 題目描述 如題,給定一個範圍N,你需要處理M個某數字是否為質數的詢問(每個數字均在範圍1-N內) 輸入輸出格式 輸入格式: 第一行包含兩個正整數N、M,分別表示查詢的範圍和查詢的個數。 接
洛谷 P3383 【模板】線性篩素數
toolbar left 整數 show scan fin names 一行 bar P3383 【模板】線性篩素數 題目描述 如題,給定一個範圍N,你需要處理M個某數字是否為質數的詢問(每個數字均在範圍1-N內) 輸入輸出格式 輸入
【模板】線性求逆元(洛谷P3367)
Description 給定\(n\),\(p\)求\(1~n\)中所有整數在模\(p\)意義下的乘法逆元。 Input 一行\(n\),\(p\) Output \(n\)行,第\(i\)行表示\(i\)在模\(p\)意義下的逆元。 Solution #include<c
【模板】線性篩(洛谷P3383)
Description 如題,給定一個範圍\(N\),你需要處理\(M\)個某數字是否為質數的詢問(每個數字均在範圍\(1-N\)內) Input 第一行包含兩個正整數\(N\)、\(M\),分別表示查詢的範圍和查詢的個數。 接下來\(M\)行每行包含一個不小於1且不大於\(N\)的整數,即
基礎題 P3383 【模板】線性篩素數 洛谷 簡單
題目描述 如題,給定一個範圍N,你需要處理M個某數字是否為質數的詢問(每個數字均在範圍1-N內) 輸入輸出格式 輸入格式: 第一行包含兩個正整數N、M,分別表示查詢的範圍和查詢的個數。 接下來M行每行包含一個不小於1且不大於N的整數,即詢問該數是否為質數。 輸出格式: 輸出包含M
[洛谷]P3383 【模板】線性篩素數 (#數學 -1.15)
題目描述 如題,給定一個範圍N,你需要處理M個某數字是否為質數的詢問(每個數字均在範圍1-N內) 輸入輸出格式 輸入格式: 第一行包含兩個正整數N、M,分別表示查詢的範圍和查詢的個數。 接下來M行每行包含一個不小於1且不大於N的整數,即詢問該數是否為質數。 輸出格式:
luogu P3383 【模板】線性篩素數
強推洛穀日報 寫的超棒! (洛穀日報裡的文章都超好 (所以我就不說什麼了 質數判定方法 #include<cstdio> #include<cstring> using namespace std; #define maxn 10000010 in
【模板】線性篩素數(埃篩+歐篩)
本來打算自己寫一篇的,但在找埃篩的程式碼時找到了一篇不錯的題解,修改了一點內容上的表述分享出來,原作者的洛谷ID為 dormantbs 我們常說的線篩是指線上性時間內把素數篩出來的過程,這裡介紹兩種篩法. 一般篩法(埃拉託斯特尼篩法,之後簡稱為埃篩): 基
數論——【模板】線性篩素數
題目來源 洛谷P3383【模板】線性篩素數 https://www.luogu.org/problem/show?pid=3383 思路 線性篩素數模板題 時間複雜度:O(n) 程式碼(C++
【轉載】線性基的更多操作!
一位 如果 xor 不可 異或 包含 最大 處理 最大值 查詢某個數 轉自帥到報警 就是查找某個數是否可以由這 n 個數中任一個數異或得到。首先還是剛才那個定理:線性基的值域與原數組的值域相同。 還有我們要發現一個性質:如果 x1 ^ x1 = x3, 那麽 x3 ^ x
線性基【模板】
文章目錄題目連結: 題目連結: #include"bits/stdc++.h" using namespace std; typedef long long LL; const int maxn=1e
【模板】合併模線性方程組(POJ2891)
Description 給定\(n\)組同餘關係,求解最小的非負整數\(x\),滿足\(x \mod a_i = r_i\) Input 第一行一個整數\(n\) 接下來\(n\)行,每行兩個整數,分別表示\(a_i\) 和 \(r_i\) Output 一個正整數\(x\)即最小正