您的位置:首页 > 其它

sgu275 线性基模板题

2017-11-27 19:24 134 查看
高斯消元求线性基,O(nlogw),两种写法。第二种代码短,但是不能保证性质。

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
#define N 55
inline ll read(){
ll x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
return x*f;
}
int n;
ll a
,p[62],ans=0;
inline void getbasic(){
for(int i=1;i<=n;++i)
for(int j=60;j>=0;--j){
if(!(a[i]>>j)) continue;//对线性基的这一位没贡献
if(!p[j]){
p[j]=a[i];
for(int k=j-1;k>=0;--k) if(p[j]>>k&1) p[j]^=p[k];
for(int k=j+1;k<=60;++k) if(p[k]>>j&1) p[k]^=p[j];
break;
}//选入线性基中
a[i]^=p[j];
}
}
int main(){
//  freopen("a.in","r",stdin);
n=read();for(int i=1;i<=n;++i) a[i]=read();
getbasic();
for(int i=0;i<=60;++i) ans^=p[i];//贪心的全取。这样是对角矩阵。
printf("%lld\n",ans);
return 0;
}


或者这样写

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
#define N 55
inline ll read(){
ll x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
return x*f;
}
int n;
ll a
,p[62],ans=0;
inline void getbasic(){
for(int i=1;i<=n;++i)
for(int j=60;j>=0;--j){
if(!(a[i]>>j)) continue;//对线性基的这一位没贡献
if(!p[j]){p[j]=a[i];break;}//选入线性基中
a[i]^=p[j];
}
}
int main(){
//  freopen("a.in","r",stdin);
n=read();for(int i=1;i<=n;++i) a[i]=read();
getbasic();
for(int i=60;i>=0;--i)
if((ans^p[i])>ans) ans^=p[i];//这样做只是上三角矩阵,贪心时需要判断一下
printf("%lld\n",ans);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: