Reference Blog:
https://blog.csdn.net/a_forever_dream/article/details/83654397
https://ouuan.github.io/%E7%BA%BF%E6%80%A7%E5%9F%BA%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/
https://blog.sengxian.com/algorithms/linear-basis
Linear basis properties:
1. Any number in the original sequence can be obtained by some number exclusion in the linear basis.
2. Any number difference in the linear basis can not get 0 000.
3. The number of numbers in a linear basis is unique, and the number of numbers is the smallest while preserving property 1.
Problems solved
1. Maximum XOR sum
2. What is the largest difference in kk?
3. Find the sum of all XOR values
[example] Linear Basis of P3812 [Template]
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int M = 70; 5 typedef struct LB{ 6 ll d[M]; 7 void Insert( ll x ){ 8 ll t = x ; 9 for(ll i=62;i>=0;i--){ 10 if( (x & (1ll<<i)) ){ 11 if( d[i] ){ 12 x ^= d[i]; 13 }else { 14 d[i] = x; 15 break; 16 } 17 } 18 } 19 } 20 ll Max(){ 21 ll ans = 0 ; 22 for(int i=62;i>=0;i--){ 23 ans = max( ans , ans ^ d[i] ); 24 } 25 return ans; 26 } 27 }LB; 28 LB s; 29 int n; 30 ll a[M]; 31 int main() 32 { 33 scanf("%d",&n); 34 for(int i=1;i<=n;i++){ 35 scanf("%lld",&a[i]); 36 s.Insert(a[i]); 37 } 38 39 return printf("%lld\n",s.Max())*0; 40 }
[example] P4570 [BJWC2011] elements
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int M = 70; 5 const int N = 1e3+10; 6 typedef struct Node { 7 ll No; 8 ll val; 9 bool operator < ( const Node & rhs) const { 10 return val > rhs.val; 11 } 12 }Node ; 13 Node a[N]; 14 typedef struct LB{ 15 ll d[M]; 16 bool Insert( ll x ){ 17 for(int i=62;i>=0;i--){ 18 if( (1ll<<i) & x ){ 19 if(d[i]){ 20 x ^= d[i]; 21 }else{ 22 d[i] = x ; 23 return true; 24 } 25 } 26 } 27 return false ; 28 } 29 30 }LB; 31 LB s; 32 int n; 33 int main() 34 { 35 scanf("%d",&n); 36 for(int i=1;i<=n;i++){ 37 scanf("%lld%lld",&a[i].No,&a[i].val); 38 } 39 sort( a+1 , a+1+n ); 40 ll ans = 0 ; 41 for(int i=1;i<=n;i++){ 42 if( s.Insert(a[i].No) ) 43 ans += a[i].val; 44 } 45 return printf("%lld\n",ans)*0; 46 }
[example] P3857 [TJOI2008] Color Lamp
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int N = 100; 5 char s[N][N]; 6 ll a[N]; 7 int n,m; 8 struct LB{ 9 ll d[70]; 10 bool Insert( ll x ){ 11 for(int i=62;i>=0;i--){ 12 if( (x>>i)&1 ){ 13 if(!d[i]){ 14 d[i] = x ; 15 return true; 16 }else{ 17 x ^= d[i] ; 18 } 19 } 20 } 21 return false ; 22 } 23 }S; 24 int main() 25 { 26 scanf("%d%d",&m,&n); 27 for(int i=1;i<=n;i++){ 28 scanf("%s",s[i]); 29 } 30 for(int i=1;i<=n;i++){ 31 32 for(int j=m-1;j>=0;j--){ 33 a[i] = a[i]+ (1ll*(s[i][j]=='O')<<(m-1-j)) ; 34 } 35 //printf("%lld\n",a[i]); 36 } 37 int k = 0 ; 38 for(int i=1;i<=n;i++){ 39 if( S.Insert(a[i]) ) 40 k++; 41 } 42 43 ll ans = 1 ; 44 for(int i=1;i<=k;i++){ 45 ans = (ans<<1) % 2008 ; 46 } 47 printf("%lld\n",ans); 48 return 0; 49 }
[example] P3292 [SCOI2016] Lucky Number
1 // luogu-judger-enable-o2 2 #include<cstdio> 3 #include<cctype> 4 #include<cstring> 5 #include<algorithm> 6 using namespace std; 7 typedef long long ll; 8 const int N = 20010; 9 const int M = 60 ; 10 11 template < class T > 12 void read( T& x ){ 13 x = 0; 14 int f = 1 ; 15 char c = getchar() ; 16 while( c<'0'||c>'9' ) { 17 if (c == '-') f = -1; 18 c = getchar(); 19 } 20 while( c>='0'&&c<='9' ) { 21 x = x * 10 + c - '0'; 22 c = getchar(); 23 } 24 x = x * f ; 25 } 26 inline ll max( ll x,ll y ){ 27 return x > y ? x : y ; 28 } 29 typedef struct Edge { 30 int to , next ; 31 }Edge ; 32 Edge e[N<<1] ; 33 int n,Q,head[N],cnt; 34 35 inline void add_edge(int u,int v){ 36 e[ cnt ] = Edge{ v , head[u] }; 37 head[u] = cnt ++ ; 38 } 39 40 ll G[N],p[N][16][M+1],Ans[M+1]; //Value, Linear Basis on Trees, Linear Basis of Answers 41 int up[N][16],dep[N] ; //Prefix second^k Ge and Deep 42 43 inline void Insert( ll x ){ 44 for(int i = M ; ~i ; i-- ){ 45 if( x >> i ){ 46 if( !Ans[i] ) { Ans[i] = x ; break ; } 47 else x ^= Ans[i] ; 48 } 49 } 50 } 51 inline void Insert( int u , int d , ll x ){ 52 for(int i = M ; ~i ; i-- ){ 53 if( x >> i ){ 54 if( !p[u][d][i] ) { p[u][d][i] = x ; break; } 55 else x ^= p[u][d][i] ; 56 } 57 } 58 } 59 60 void dfs(int u,int Fa){ 61 dep[u] = dep[Fa] + 1 ; 62 up[u][0] = Fa ; 63 64 Insert( u , 0 , G[u] ); 65 66 for(int i=1 ; i <= 15 ; i++ ){ 67 68 up[u][i] = up[up[u][i-1]][i-1]; // Dad's dad is Grandpa 69 70 if( !up[u][i] ) break; // Because the root node is an empty point 0 71 72 for( int j=M ; ~j ; j-- ){ 73 if( p[u][i-1][j] ) Insert( u , i , p[u][i-1][j] ); 74 if( p[up[u][i-1]][i-1][j] ) Insert( u , i ,p[up[u][i-1]][i-1][j] ); 75 } 76 } 77 for( register int i = head[u] ; ~i ; i=e[i].next ){ 78 if( e[i].to != Fa ) dfs( e[i].to , u ) ; 79 } 80 } 81 ll query ( int u , int v ){ 82 memset( Ans , 0 , sizeof Ans ); //For multiple queries, empty the linear basis 83 84 if( dep[u] < dep[v] ) swap(u, v); //default u For a lower point 85 86 for(int i=15;~i;i--){ //Using the idea of binary, climb to the same height 87 if( dep[up[u][i]] >= dep[v] ){ //At the same time, the value of the corresponding node is inserted into the linear basis for the climbing process. 88 for(int j=M;~j;j--) 89 if( p[u][i][j] ) Insert( p[u][i][j] ); 90 u = up[u][i] ; 91 } 92 } 93 94 if( u^v ){ //For different positions, we need to take steps at the same time. 95 for(int i=15;~i;i--){ 96 if( up[u][i] != up[v][i] ){ //Both sides insert the value of the corresponding node position into the linear basis of the answer. 97 for(int j=M;~j;j--){ 98 if( p[u][i][j] ) Insert( p[u][i][j] ); 99 if( p[v][i][j] ) Insert( p[v][i][j] ); 100 } 101 u = up[u][i] , v = up[v][i]; 102 } 103 } 104 Insert(G[u]), Insert(G[v]), Insert(G[up[u][0]]); 105 }else Insert(G[u]); 106 107 ll res = 0; 108 for(int j=M ; ~j ;j-- ){ 109 res = max ( res , res^Ans[j] ); 110 } 111 return res ; 112 } 113 114 int main(){ 115 memset( head,-1,sizeof head ); 116 read(n) , read(Q) ; 117 for( register int i=1 ; i<=n;i++ ) read(G[i]); 118 int u,v ; 119 for( register int i=1 ; i^n ;i++ ) { 120 read(u) , read(v) ; 121 add_edge(u, v), add_edge(v, u); 122 } 123 dfs(1, 0); 124 125 while( Q-- ){ 126 read(u), read(v) ; 127 printf("%lld\n",query(u,v)); 128 } 129 return 0 ; 130 } 131 132 /* 133 * 134 4 2 135 11 5 7 9 136 1 2 137 1 3 138 1 4 139 2 3 140 1 4 141 142 14 143 11 144 */