sgu275 线性基模板题

来源:互联网 发布:网络直播社会现象 编辑:程序博客网 时间:2024/06/01 08:09

高斯消元求线性基,O(nlogw),两种写法。第二种代码短,但是不能保证性质。

#include <bits/stdc++.h>using namespace std;#define ll long long#define inf 0x3f3f3f3f#define N 55inline 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[N],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 55inline 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[N],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;}
原创粉丝点击