线性基

不懂~网上说的也没看懂,有空好好学习下。。。

dalaohttp://www.cnblogs.com/candy99/p/6653743.html

XOR

 HDU - 3949

题意:求异或和第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:
",++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
",query(k));
49         }
50     }
51 }
View Code

还是不懂~

模板错了坑死=_=

 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:
", ++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
", lb.kth(k));
62         }
63     }
64 }
View Code

新Nim游戏

 HYSBZ - 3105 

 题意:一些数,选择一个权值最大的异或和不为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
",sum-ans);
39 }
View Code

元素

 HYSBZ - 2460

题意:和上一题基本一样~

 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
",ans);
40 }
View Code

我可能懂了点皮毛~

原文地址:https://www.cnblogs.com/yijiull/p/7358115.html