zoukankan      html  css  js  c++  java
  • 线性基

    线性基

    https://blog.csdn.net/a_forever_dream/article/details/83654397这个博客学习的

    看完了博客虽然还是不能完全理解线性基,但是大概懂了是怎么用的

    1.求一个序列的最大/最小异或

    2.求一个序列第k小异或

    下面是一些入门题:

    To xor or not to xor SGU - 275

    求n个数的最大异或

    #include <cstdio>
    long long d[70];
    int main() {
        int n;
        scanf("%d", &n);
        long long a, ans = 0;
        for(int i = 0; i < n; i++) {
            scanf("%lld", &a);
            for(int j = 60; j >= 0; j--) {
                if(a & (1LL << j)) {
                    if(d[j]) a ^= d[j];
                    else {
                        d[j] = a;
                        break;
                    }
                }
            }
        }
        for(int i = 60; i >= 0; i--) {
            if((ans ^ d[i]) > ans) ans ^= d[i];
        }
        printf("%lld
    ", ans);
        return 0;
    }
    

    P4570 [BJWC2011]元素

    #include <cstdio>
    #include <algorithm>
    using std::sort;
    typedef long long LL;
    struct node
    {
        LL a, b;
    }G[1010];
    bool cmp(node x, node y) {
        return x.b > y.b;
    }
    LL d[110];
    int main() {
        int n;
        LL ans = 0;
        scanf("%d", &n);
        for(int i = 0; i < n; i++) {
            scanf("%lld %lld", &G[i].a, &G[i].b);
        }
        sort(G, G +n, cmp);
        for(int i = 0; i < n; i++) {
            for(int j = 60; j >= 0; j--) {
                if(G[i].a & (1LL << j)) {
                    if(d[j]) G[i].a ^= d[j];
                    else {
                        d[j] = G[i].a;
                        ans += G[i].b;
                        break;
                    }
                }
            }
        }
        printf("%lld
    ", ans);
        return 0;
    }
    

    P3857 [TJOI2008]彩灯

    #include <cstdio>
    typedef long long LL;
    LL d[110];
    int main() {
        int n, m;
        scanf("%d %d", &n, &m);
        while(m--) {
            char s[110];
            LL a = 0;
            scanf("%s", s);
            for(int i = 0; i < n; i++) {
                if(s[i] == 'O') {
                    a += (1LL << (n - i - 1));
                }
            }
            //printf("aa %lld
    ", a);
            for(int i = 60; i >= 0; i--) {
                if(a & (1LL << i)) {
                    if(d[i]) a ^= d[i];
                    else {
                        d[i] = a;
                        break;
                    }
                }
            }
        }
        int cnt = 0;
        for(int i = 0; i <= 60; i++) {
            if(d[i]) cnt++;
        }
        printf("%lld
    ", (1LL << cnt) % 2008);
        return 0;
    }
    

    XOR HDU - 3949

    t组数据,n个数的序列,q组询问第k小的异或值。

    #include <cstdio>
    #include <cstring>
    typedef long long LL;
    LL d[70];
    
    int main() {
        int t;
        scanf("%d", &t);
        for(int k = 1; k <= t; k++) {
            printf("Case #%d:
    ", k);
            memset(d, 0, sizeof(d));
            int n;
            LL a;
            scanf("%d", &n);
            for(int i = 0; i < n; i++) {
                scanf("%lld", &a);
                for(int j = 60; j >= 0; j--) {
                    if(a & (1LL << j)) {
                        if(d[j]) a ^= d[j];
                        else {
                            d[j] = a;
                            break;
                        }
                    }
                }
            }
            int cnt = 0;
            for(int i = 0; i <= 60; i++) {
                if(d[i]) cnt++;
            }
            //printf("cnt %d
    ", cnt);
            for(int i = 1; i <= 60; i++) {
                for(int j = 1; j <= i; j++) {
                    if(d[i] & (1LL << (j - 1))) d[i] ^= d[j-1];
                }
            }
            int q;
            scanf("%d", &q);
            while(q--) {
                scanf("%lld", &a);
                if(a == 1 && cnt < n) {
                    printf("0
    ");
                    continue;
                }
                if(cnt < n && (1LL << cnt) < a) {
                    printf("-1
    ");
                    continue;
                }
                if(cnt == n && (1LL << cnt) <= a) {
                    printf("-1
    ");
                    continue;
                }
                LL ans = 0;
                if(cnt < n) a--;
                for(int i = 0; i <= 60; i++) {
                    if(d[i]) {
                        if(a % 2 == 1) ans ^= d[i];
                        a /= 2;
                    }
                }
                printf("%lld
    ", ans);
            }
        }
        return 0;
    }
    
    
  • 相关阅读:
    hdu2151
    hdu1028
    hdu1398
    hdu1465
    hdu2853
    poj2195
    poj2255
    JS正则校验数字,特殊字符,邮箱基本格式
    JS正则校验数字,特殊字符,邮箱基本格式
    io读取文件内容乱码处理
  • 原文地址:https://www.cnblogs.com/fanshhh/p/12601500.html
Copyright © 2011-2022 走看看