zoukankan      html  css  js  c++  java
  • 2017 ICPC西安区域赛 A

    链接:https://nanti.jisuanke.com/t/A1607

    题面:

     

    Consider an array AA with n elements . Each of its element is A[i]A[i(1 le i le n)(1in) . Then gives two integers QQ, KK, and QQ queries follow . Each query , give you LL, RR, you can get ZZ by the following rules.

    To get ZZ , at first you need to choose some elements from A[L]A[L] to A[R]A[R] ,we call them A[i_1],A[i_2]…A[i_t]A[i1],A[i2]A[it] , Then you can get number Z = KZ=K or (A[i_1]A[i1] xor A[i_2]A[i2] … xor A[i_t]A[it]) .

    Please calculate the maximum ZZ for each query .

    Input

    Several test cases .

    First line an integer T(1 le T le 10)(1T10) . Indicates the number of test cases.Then TT test cases follows . Each test case begins with three integer NN, QQ, K(1 le N le 10000, 1 le Q le 100000 , 0 le K le 100000)(1N10000, 1Q100000, 0K100000) . The next line has NN integers indicate A[1]A[1] to A[N]A[N(0 le A[i] le 10^8)(0A[i]108). Then QQ lines , each line two integer LL, R(1 le L le R le N)(1LRN) .

    Output

    For each query , print the answer in a single line.

    样例输入

    1
    5 3 0
    1 2 3 4 5
    1 3
    2 4
    3 5

    样例输出

    3
    7
    7

    题目来源

    ACM-ICPC 2017 Asia Xi'an

     

    跟树套树差不多,线段树每个节点建个线性基,写个合并函数,对k取反,每个数对取反后的k取且,就可以转化成线性基中取与k异或最大值了

     

    实现代码:

    #include<bits/stdc++.h>
    using namespace std;
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define mid int m = (l + r) >> 1
    const int M = 1e4+10;
    int a[M];
    struct L_B{
        int b[33],nb[33],tot;
        void init(){
            memset(b,0,sizeof(b));
        }
    
        bool Insert(int x){
            for(int i = 30;i >= 0;i --){
                if(x&(1<<i)){
                    if(!b[i]){
                        b[i] = x;
                        break;
                    }
                    x ^= b[i];
                }
            }
            return x > 0;
        }
    
        int Max(int x){
            int ret = x;
            for(int i = 30;i >= 0;i --)
                ret = max(ret,ret^b[i]);
            return ret;
        }
    
        int Min(int x){
            int ret = x;
            for(int i = 0;i <= 30;i ++)
                if(b[i]) ret ^= b[i];
            return ret;
        }
    
        void rebuild(){
            for(int i = 30;i >= 0;i --)
                for(int j = i-1;j >= 0;j --)
                    if(b[i]&(1<<j)) b[i]^=b[j];
            for(int i = 0;i <= 30;i ++)
                if(b[i]) nb[tot++] = b[i];
        }
    
        int K_Min(int k){
            int res = 0;
            if(k >= (1<<tot))
                return -1;
            for(int i = 30;i >= 0;i --)
                if(k&(1<<i))
                    res ^= nb[i];
            return res;
        }
    
        L_B merge(L_B v){
            L_B ret;
            for(int i = 0;i <= 30;i ++) ret.b[i] = b[i];
            for(int i = 0;i <= 30;i ++){
                for(int j = i;j >= 0;j --){
                    if(v.b[i]&(1<<j)){
                        if(ret.b[j]) v.b[i] ^= ret.b[j];
                        else {
                            ret.b[j] = v.b[i]; break;
                        }
                    }
                }
            }
            return ret;
        }
    }t[M<<2];
    
    void build(int l,int r,int rt){
        if(l == r){
            t[rt].init();
            t[rt].Insert(a[l]);
            return ;
        }
        mid;
        build(lson); build(rson);
        t[rt] = t[rt<<1].merge(t[rt<<1|1]);
    }
    
    L_B query(int L,int R,int l,int r,int rt){
        if(L <= l&&R >= r){
            return t[rt];
        }
        mid;
        if(L <= m&&m < R) return query(L,R,lson).merge(query(L,R,rson));
        if(L <= m) return query(L,R,lson);
        if(R > m) return query(L,R,rson);
    }
    
    int main()
    {
        int T,n,q,k,l,r;
        scanf("%d",&T);
        while(T--){
            scanf("%d%d%d",&n,&q,&k);
            k = ~k;
            for(int i = 1;i <= n;i ++)
                scanf("%d",&a[i]),a[i]&=k;
            k = ~k;
            build(1,n,1);
            for(int i = 1;i <= q;i ++){
                scanf("%d%d",&l,&r);
                L_B ans = query(l,r,1,n,1);
                int an = ans.Max(k);
                printf("%d
    ",an);
            }
        }
        return 0;
    }
  • 相关阅读:
    官方下载python源码,编译linux版本的python
    bootstrap冻结窗口
    LeetCode之TwoSum
    MyISAM和InnoDB索引实现对比(总结)
    InnoDB的三个关键特性(总结)
    InnoDB与MyISAM总结和对比(总结)
    C++类库开发之导出类设计原则
    C++类库开发详解
    C#各种配置文件使用,操作方法总结
    C/C++代码优化的27条建议
  • 原文地址:https://www.cnblogs.com/kls123/p/10849792.html
Copyright © 2011-2022 走看看