线性基
不懂~网上说的也没看懂,有空好好学习下。。。
dalaohttp://www.cnblogs.com/candy99/p/6653743.html
XOR
题意:求异或和第k小的数。
1 #include <bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 const int maxn=1e4+10; 5 ll bin[maxn],a[maxn],k; 6 int n; 7 void init(){ 8 bin[0]=1; 9 for(int i=1;i<=60;i++) bin[i]=bin[i-1]<<1; 10 } 11 int now; 12 13 void gauss(int n){ 14 now=1; 15 for(int i=60;i>=0;i--){ 16 int j=now; 17 while(j<=n&&!(a[j]&bin[i])) j++; 18 if(j==n+1) continue; 19 if(j!=now) swap(a[j],a[now]); 20 for(int k=1;k<=n;k++) if(k!=now){ 21 if(a[k]&bin[i]) a[k]^=a[now]; 22 } 23 now++; 24 } 25 now--; 26 } 27 ll query(ll k){ 28 ll ans=0; 29 if(now!=n) k--; //now!=n说明n个数线性相关,异或可以为0 30 if(k>=bin[now]) return -1; 31 for(int i=1;i<=now;i++) 32 if(k&bin[now-i]) ans^=a[i]; 33 return ans; 34 } 35 int main(){ 36 int t,kase=0; 37 scanf("%d",&t); 38 init(); 39 while(t--){ 40 printf("Case #%d:\n",++kase); 41 scanf("%d",&n); 42 for(int i=1;i<=n;i++) scanf("%lld",&a[i]); 43 gauss(n); 44 int q; 45 scanf("%d",&q); 46 while(q--){ 47 scanf("%lld",&k); 48 printf("%lld\n",query(k)); 49 } 50 } 51 }
还是不懂~
模板错了坑死=_=
1 #include <bits/stdc++.h> 2 using namespace std; 3 #define LL long long 4 struct LiBase{ 5 LL a[63],p[63]; 6 int cnt; // 重建后,该线性基的范围是[1,1<<(cnt)-1] 7 //初始化 8 void init(){ 9 cnt=0; 10 memset(a,0,sizeof(a)); 11 memset(p,0,sizeof(p)); 12 } 13 //插入 14 bool insert(LL x){ 15 for(int i=62;i>=0&&x;i--)if(x&(1LL<<i)){ 16 if(!a[i]){ 17 a[i]=x; 18 break; 19 }else x^=a[i]; 20 } 21 return x>0; 22 } 23 //重建 24 void rebuild(){ 25 for(int i=62;i>=0;i--) 26 for(int j=i-1;j>=0;j--) if(a[i]&(1LL<<j)) a[i]^=a[j]; 27 for(int i=0;i<=62;i++) if(a[i]) p[cnt++]=a[i]; 28 } 29 //第k小 30 LL kth(LL k){ 31 LL ans=0; 32 if(k>=(1LL<<cnt)) return -1; 33 for(int i=cnt-1;i>=0;i--){ 34 if(k&(1LL<<i)) ans^=p[i]; 35 } 36 return ans; 37 } 38 }; 39 LiBase lb; 40 int main(){ 41 int t, kase = 0; 42 //freopen("in.txt", "r", stdin); 43 scanf("%d", &t); 44 while(t--){ 45 lb.init(); 46 int n; 47 scanf("%d", &n); 48 LL x; 49 for(int i = 0 ; i < n; i++){ 50 scanf("%lld", &x); 51 lb.insert(x); 52 } 53 lb.rebuild(); 54 int q; 55 LL k; 56 printf("Case #%d:\n", ++kase); 57 scanf("%d", &q); 58 for(int i = 0 ; i < q; i++){ 59 scanf("%lld", &k); 60 if(lb.cnt != n) k--; 61 printf("%lld\n", lb.kth(k)); 62 } 63 } 64 }
新Nim游戏
题意:一些数,选择一个权值最大的异或和不为0的集合
1 #include <bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 const int maxn=110; 5 6 int a[maxn]; 7 ll bin[36]; 8 int pivot[36]; 9 ll ans; 10 void init(){ 11 bin[0]=1; 12 for(int i=1;i<=35;i++) bin[i]=bin[i-1]<<1; 13 } 14 void gauss(int n){ 15 for(int i=1;i<=n;i++){ 16 int temp=a[i]; 17 for(int j=35;j>=0;j--) if(a[i]&bin[j]){ 18 if(pivot[j]) a[i]^=a[pivot[j]]; 19 else {pivot[j]=i;break;} 20 } 21 if(a[i]) ans+=temp; 22 } 23 } 24 25 int main(){ 26 int n; 27 init(); 28 scanf("%d",&n); 29 ll sum=0; 30 for(int i=1;i<=n;i++){ 31 scanf("%d",&a[i]); 32 sum+=a[i]; 33 } 34 sort(a+1,a+n+1,greater<int>()); 35 ans=0; 36 gauss(n); 37 if(ans==0) puts("-1"); 38 else printf("%lld\n",sum-ans); 39 }
元素
题意:和上一题基本一样~
1 #include <bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 const int maxn=1010; 5 6 struct Node{ 7 ll id,m; 8 bool operator <(const Node& a)const { 9 return m>a.m; 10 } 11 }node[maxn]; 12 ll bin[64]; 13 int pivot[64]; 14 ll ans; 15 void init(){ 16 bin[0]=1; 17 for(int i=1;i<=60;i++) bin[i]=bin[i-1]<<1; 18 } 19 void gauss(int n){ 20 for(int i=1;i<=n;i++){ 21 for(int j=60;j>=0;j--) if(node[i].id&bin[j]){ 22 if(pivot[j]) node[i].id^=node[pivot[j]].id; 23 else {pivot[j]=i;break;} 24 } 25 if(node[i].id) ans+=node[i].m; 26 } 27 } 28 29 int main(){ 30 int n; 31 init(); 32 scanf("%d",&n); 33 for(int i=1;i<=n;i++){ 34 scanf("%lld%lld",&node[i].id,&node[i].m); 35 } 36 sort(node+1,node+n+1); 37 ans=0; 38 gauss(n); 39 printf("%lld\n",ans); 40 }
我可能懂了点皮毛~