线性基 刷题记录
Posted jiecaoer
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线性基 刷题记录相关的知识,希望对你有一定的参考价值。
HDU3949 XOR
- 线性基板子题
- 给定一些数
- 求这些数能通过异或得到的第k大的值。
- 代码:
1 #include <bits/stdc++.h> 2 #define nmax 10010 3 4 using namespace std; 5 typedef long long ll; 6 ll a[nmax],b[70],k[70]; //k[i] 第i小的数 7 int n,q; 8 9 int main() 10 //freopen("owo.in","r",stdin); 11 int T; 12 cin>>T; 13 for (int cas=1; cas<=T; cas++) 14 memset(b,0,sizeof(b)); 15 memset(k,0,sizeof(k)); 16 printf("Case #%d:\n",cas); 17 scanf("%d",&n); 18 for (int i=0; i<n; i++) 19 scanf("%lld",&a[i]); 20 //求线性基 21 for (int j=61; j>=0; j--) 22 if(a[i]&(1LL<<j)) 23 if(b[j]) a[i]^=b[j]; 24 else b[j]=a[i]; break; 25 26 27 28 //往上回代,顺便统计个数 29 int cnt=0; 30 for (int i=0; i<=61; i++) if(b[i]) 31 k[cnt]=b[i]; 32 cnt++; 33 for (int j=i+1; j<=61; j++) if(b[j]&(1LL<<i)) b[j]^=b[i]; 34 35 ll mmax=(1LL<<cnt)-1; 36 scanf("%d",&q); 37 ll inq; 38 bool flag=false; 39 if(cnt<n) flag=true; 40 for (int j=0; j<q; j++) 41 scanf("%lld",&inq); 42 if(flag) inq--; 43 if(inq>mmax) cout<<-1<<endl; 44 else 45 ll ans=0; 46 for (int i=0; (1LL<<i)<=inq; i++) if((1LL<<i)&inq) ans^=k[i]; 47 printf("%lld\n",ans); 48 49 50 51 return 0; 52
BZOJ 2115: [Wc2011] Xor
- 题意,一个无向图,节点编号1~n,求从1到n的一条路径,边和点可以经过多次,求经过边的权值xor最大的那一条路径
- 题解:随便找一条路径从1~n的,然后可以发现任意路径都可以表示为在这条路径上走环,所以找出所有的环
- 然后就是在所有的环里找和主路径异或最大的
- 找所有的环用dfs
- 代码:
1 #include <bits/stdc++.h> 2 #define nmax 50010 3 #define mmax 100010 4 5 using namespace std; 6 typedef long long ll; 7 int head[nmax]=0,d[nmax]=0; //被vis到的顺序 8 ll a[nmax+mmax],tmp[nmax],b[70]=0; 9 int n,m,idx=0,idxa=0; //idza是记录环的数量 10 struct edge 11 int v,ne; 12 ll w; 13 e[mmax*2]; 14 15 inline void addedge(int u,int v,ll w) 16 idx++; 17 e[idx].v=v; 18 e[idx].w=w; 19 e[idx].ne=head[u]; 20 head[u]=idx; 21 22 23 void build() 24 cin>>n>>m; 25 int a,b; ll c; 26 for (int i=0; i<m; i++) 27 scanf("%d%d%lld",&a,&b,&c); 28 addedge(a,b,c); 29 addedge(b,a,c); 30 31 32 33 void dfs(int u,int cnt) 34 d[u]=cnt; 35 for (int i=head[u]; i; i=e[i].ne) 36 int v=e[i].v; ll w=e[i].w; 37 if(d[v]>d[u]) continue; 38 if(d[v]) 39 ll x=tmp[v]^tmp[u]^w; //这个环的xor值 40 //cout<<"now u= "<<u<<" v= "<<v<<" and x= "<<x<<endl; 41 if(x) a[++idxa]=x; //如果是0就舍弃 42 else 43 tmp[v]=tmp[u]^w; //在dfs(u)之前,u的tmp值已经算出 44 dfs(v,cnt+1); 45 46 47 48 49 void xxj() 50 for (int i=1; i<=idxa; i++) for (int j=63; j>=0; j--) if((1LL<<j)&a[i]) 51 if(b[j]) a[i]^=b[j]; 52 else b[j]=a[i]; break; 53 54 ll ans=tmp[n]; 55 for (int i=63; i>=0; i--) ans=max(ans,ans^b[i]); 56 printf("%lld\n",ans); 57 58 59 int main() 60 build(); 61 dfs(1,1); 62 xxj(); 63 return 0; 64
以上是关于线性基 刷题记录的主要内容,如果未能解决你的问题,请参考以下文章