日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

【模板】线性基

發(fā)布時(shí)間:2023/12/3 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【模板】线性基 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

ACM模板


文章目錄

      • 構(gòu)造線性基
      • 線性基模板操作
      • 線性基相關(guān)題目

學(xué)習(xí)線性基可考慮以下大佬博客
知乎Pecco博客
博客園Kaori博客
menci博客
肖然博客
從線性代數(shù)談線性基(有點(diǎn)硬核)

構(gòu)造線性基

普通插入:
不能保證除了主元上其他線性基元素該位置為1

typedef unsigned long long ull; ull p[64]; void insert(ull x) {for(int i=63;i>=0;i--){if(!(x>>i&1)) continue;if(!p[i]) {p[i]=x;break;}x^=p[i];} }

進(jìn)階插入:

若p[i]!=0(即主元i存在),則線性基中只有p[i]的第i位是1;且此時(shí)p[i]的最高位就是第i位

bool insert(ll x) {for(int i=62;i>=0;i--){if(!(x>>i&1)) continue;if(p[i]){x^=p[i];continue;}for(int j=i-1;j>=0;j--)if(x>>j&1) x^=p[j];for(int j=62;j>i;j--)if(p[j]>>i&1) p[j]^=x;p[i]=x;return 1;}return 0; }

線性基模板操作

1.在一系列數(shù)中選若干數(shù)做異或,求最大值。

反向遍歷p[]數(shù)組,按高位貪心(因?yàn)閷?duì)于每個(gè)p[i]來(lái)說(shuō),當(dāng)且僅當(dāng)目前的res的第i位為0時(shí),選這個(gè)數(shù)可以使res增大。而此時(shí),選它一定比不選它更優(yōu))

普通插入代碼:

ull getmax() {ull res=0;for(int i=63;i>=0;i--)if((res^p[i])>res) res^=p[i];return res; }

進(jìn)階插入:直接把所有p[i]異或即是最大值。

2.在一系列數(shù)中選若干數(shù)做異或,求最小值。

直接求線性基,然后選最小的一個(gè)即可。顯然它與線性基中任意其他數(shù)異或后,都不會(huì)更小。
注意:特判0

普通插入代碼:

ull getmin() {if(cnt0) return 0;for(int i=0;i<=63;i++)if(p[i]) return p[i]; }

進(jìn)階插入:找到最小主元即可

3.查詢某數(shù)是否能被表示出來(lái)

按照插入的思路進(jìn)行檢查即可。

bool belong(ull x) {for(int i=63;i>=0;i--){if(!(x>>i&1)) continue;if(!p[i]) return false;x^=p[i];}return true; }

4.查詢第k小值

使用進(jìn)階插入解決此問(wèn)題,把k進(jìn)行二進(jìn)制分解,把1對(duì)應(yīng)位置的主元xor起來(lái)。
注意:第0小是0

ll now[64]; int cnt=0; for(int i=0;i<=62;i++)if(p[i]) now[cnt++]=p[i]; ll query(ll k) {if(flag) k--;if(!k) return 0;if(k>=(1ull<<cnt)) return -1;ll res=0;for(int i=0;i<cnt;i++)if(k>>i&1) res^=now[i];return res; }

線性基相關(guān)題目

【模板】線性基
普通插入即可解決

#include<iostream> #include<algorithm> using namespace std; typedef long long ll; typedef unsigned long long ull; const int N=70; ull p[N]; int n; void insert(ull x) {for(int i=63;i>=0;i--){if(!(x>>i&1)) continue;if(!p[i]) {p[i]=x;break;}x^=p[i];} } int main() {cin>>n;for(int i=1;i<=n;i++) {ull x;cin>>x;insert(x);}ull res=0;for(int i=63;i>=0;i--)if((res^p[i])>res) res^=p[i];//不難發(fā)現(xiàn)只有(res>>i&1)==0是才會(huì)滿足if語(yǔ)句cout<<res<<'\n';return 0; }

異或運(yùn)算
第k異或小,使用進(jìn)階插入即可解決。

#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; typedef long long ll; typedef unsigned long long ull; const int N=10010; ll p[70]; int n,q; bool flag; ll now[70]; int cnt; bool insert(ll x) {for(int i=62;i>=0;i--){if(!(x>>i&1)) continue;if(p[i]){x^=p[i];continue;}for(int j=i-1;j>=0;j--)if(x>>j&1) x^=p[j];for(int j=62;j>i;j--)if(p[j]>>i&1) p[j]^=x;p[i]=x;return 1;}return 0; } ll query(ll k) {if(flag) k--;if(!k) return 0;if(k>=(1ull<<cnt)) return -1;ll res=0;for(int i=0;i<cnt;i++)if(k>>i&1) res^=now[i];return res; } int main() {int T;cin>>T;for(int ca=1;ca<=T;ca++){printf("Case #%d:\n",ca);memset(p,0,sizeof p);flag=0;cnt=0;cin>>n;for(int i=1;i<=n;i++){ll x;cin>>x;if(!insert(x)) flag=1;}cin>>q;for(int i=0;i<=62;i++)if(p[i]) now[cnt++]=p[i];while(q--){ll k;cin>>k;cout<<query(k)<<'\n';}}return 0; }

[BJWC2011]元素
按照magic逆序,然后線性基插入

#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0) #include<set> #include<map> #include<cmath> #include<queue> #include<string> #include<vector> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; typedef long long ll; typedef pair<int,int> pii; typedef unsigned long long ull; const int N=1010; ull p[N]; struct node {ll id,w;bool operator<(const node& o) const {return w>o.w;} }q[N]; int n; bool insert(ull x) {for(int i=63;i>=0;i--){if(!(x>>i&1)) continue;if(!p[i]) return p[i]=x,1;x^=p[i];}return 0; } int main() {IO;int T=1;//cin>>T;while(T--){cin>>n;for(int i=1;i<=n;i++) cin>>q[i].id>>q[i].w;sort(q+1,q+1+n);ll res=0;for(int i=1;i<=n;i++){if(insert(q[i].id)) res+=q[i].w;}cout<<res<<'\n';}return 0;}

Good subset
線性基+線段樹(shù)題解
搜索題解
2020/09/30 要加油哦~

總結(jié)

以上是生活随笔為你收集整理的【模板】线性基的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。