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;
    }
  • 相关阅读:
    vue自定义指令
    ZOJ Problem Set–2104 Let the Balloon Rise
    ZOJ Problem Set 3202 Secondprice Auction
    ZOJ Problem Set–1879 Jolly Jumpers
    ZOJ Problem Set–2405 Specialized FourDigit Numbers
    ZOJ Problem Set–1874 Primary Arithmetic
    ZOJ Problem Set–1970 All in All
    ZOJ Problem Set–1828 Fibonacci Numbers
    要怎么样调整状态呢
    ZOJ Problem Set–1951 Goldbach's Conjecture
  • 原文地址:https://www.cnblogs.com/kls123/p/10849792.html
Copyright © 2011-2022 走看看