线性基 刷题记录
作者:互联网
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 }
quq
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 }
owo
标签:nmax,idx,记录,int,ll,long,ans,线性,刷题 来源: https://www.cnblogs.com/jiecaoer/p/11441062.html