"Problem Analysis"
The Gaussian elimination element is a linear base.
The topic itself is not difficult, but two methods of maintaining a linear base have caused my thinking.
123456789101112 |
void
gauss(){
k=n;
F(i,1,n){
F(j,i+1,n)
if (a[j]>a[i]) swap(a[i],a[j]);
if
(!a[i]) {k=i-1;
break
;}
D(j,30,0)
if
(a[i]>>j & 1){
b[i]=j;
F(x,1,n)
if
(x!=i && a[x]>>j&1) a[x]^=a[i];
break
;
}
}
}
|
--Gaussian elimination to find linear base
123456 |
for
(
int i=1;i<=n;++i)
for
(
int
j=31;j>=0;--j)
if
((a[i]>>j)&1){
if
(!lb[j]) {lb[j]=a[i]; cnt++;
break
;}
else
a[i]^=lb[j];
}
|
--Dynamic maintenance of linear base
Without Gaussian elimination the XOR equation Group I, directly using the second method of solving, found that the direct WA flew.
(Later, I thought, actually went through the example).
So what's the difference between them?
I took a lot of groups and found that the linear basis they were finding was the same size.
But the linear base of the Gaussian elimination has a magical feature, which is the smallest number that makes the bit 1. (The smallest)
So is it necessary to write Gaussian elimination?
Obviously not necessary, do a small operation just fine.
Then changed the dynamic maintenance of linear base code, this looks like ↓
12345678910 |
for
(
int
i=1;i<=n;++i)
for
(
int
j=31;j>=0;--j)
if
((a[i]>>j)&1sbsbo.cc){
if
(!lb[j]) {lb[j]=a[i]; cnt++;
break
;}
else
a[i]^=lb[j];
}
for
(
int
i=31;i>=0;--i)
if
(lb[i]sbbtianli.cn)
for (
int
j=i-1;j>=0;--j)
if
((lb[i]>>j)&1) lb[i]^=lb[j];
|
--Revision
The magic of AC. The linear basis is the same as the Gaussian elimination.
Consider time complexity, are log*n, naturally no difference, but with which is the benevolent see of the beholder.
In fact, the Gaussian elimination will be faster (up to the limit of complexity), while the dynamic maintenance of the linear base is the standard upper limit (fog)
Code
+ View Code
Bzoj 2844 Albus is going to be the first to play--Gaussian elimination of linear radicals