• P4735 最大异或和


    链接:https://www.luogu.org/problemnew/show/P4735

    题目描述

    给定一个非负整数序列 {a}{a} ,初始长度为 NN 。

    有M个操作,有以下两种操作类型:

    1. A x:添加操作,表示在序列末尾添加一个数 xx ,序列的长度 N+1N+1 。
    2. Q l r x:询问操作,你需要找到一个位置 pp ,满足 l le p le rlpr ,使得: a[p] oplus a[p+1] oplus ... oplus a[N] oplus xa[p]a[p+1]...a[N]x 最大,输出最大是多少。

    输入输出格式

    输入格式:

    第一行包含两个整数 N,MN,M ,含义如问题描述所示。
    第二行包含 NN 个非负整数,表示初始的序列 AA 。
    接下来 MM 行,每行描述一个操作,格式如题面所述。

    输出格式:

    假设询问操作有 TT 个,则输出应该有 TT 行,每行一个整数表示询问的答案。

    输入输出样例

    输入样例#1: 复制
    5  5
    2  6 4 3 6
    A 1 
    Q 3 5 4 
    A 4
    Q 5 7 0 
    Q 3 6 6 
    输出样例#1: 复制
    4
    5
    6

    说明

    对于测试点 1-212 , N,M le 5N,M5 。
    对于测试点 3-737 , N,M le 80000N,M80000 。
    对于测试点 8-10810 , N,M le 300000N,M300000 。
    其中测试点 1, 3, 5, 7, 91,3,5,7,9 保证没有修改操作。
    0 le a[i] le 10^70a[i]107 。

    题解:

    先看简单版:

    给出 n 个数,问最大连续异或和。(n<=100000 , num<=2^31-1)
    经典贪心。再利用上异或的性质,即 b ^ a ^ b =a 。记录前缀异或和,即转化为找两个数使得其异或和最大,同前。O(n*位数)
     
    我们先来考虑,若没有添加操作,显然可以将所有的后缀异或和建成可持久化Trie树来做。那如果添加了k个元素呢?
    查询时可以将x异或上添加的k个元素,再到Trie中查询。
    建树 O(N * 位数) ;单次查询 O(k + 位数)
    注意边界,开始应该把数组整体右移,不然查询1的时候会出问题 
    #include <bits/stdc++.h>
    #define ll long long
    using namespace std;
    const int M = 600000 + 5, M_trie = M * 30;
    int root[M], a[M], bin[33], tot;
    
    struct Trie{
        
        struct node{
            int cnt[2];
            int ptr[2];
        }tree[M_trie];
        
        
        int insert(int num, int f){
            int res = ++tot; 
            int x = num, cur = res;
            tree[res] = tree[f];
            
            for(int i = 27; i; i--){
                int t = x & bin[i - 1]; t >>= (i - 1);
                int nw = ++tot;
                tree[cur].cnt[t]++;
                tree[cur].ptr[t] = nw;
                f = tree[f].ptr[t];
                tree[nw] = tree[f];
                cur = tree[cur].ptr[t];
                
            }
            return res;
        }
        
        int query(int lf, int rg, int num){
            int ans = 0;
            
            for(int i = 27; i; i--){
                int t = num & bin[i - 1]; t >>= (i - 1);
                if(tree[rg].cnt[t^1] - tree[lf].cnt[t^1]){
                    lf = tree[lf].ptr[t^1], rg = tree[rg].ptr[t^1];
                    ans += bin[i - 1];
                }
                else {
                    lf = tree[lf].ptr[t], rg = tree[rg].ptr[t];
                }    
                
            }
            
            return ans;
            
        }
        
        
    }Tr;
    
    int query(int lf, int rg, int num){
        return Tr.query(root[lf - 1], root[rg], num);
    }
    
    int main(){
    //    freopen("data.in","r",stdin);
    //    freopen("mydata.out","w",stdout);
        bin[0] = 1;
        for(int i = 1; i <= 30; i++)bin[i] = bin[i - 1] << 1;
        
        int n, q;
        scanf("%d%d", &n, &q);
        ++n;
        root[1] = Tr.insert(0, root[0]);
        for(int i = 2; i <= n; i++){
            scanf("%d", &a[i]);
            a[i] ^= a[i - 1];
            root[i] = Tr.insert(a[i], root[i - 1]);    
        }
        int cnt = n; 
        char s[5];
        int x, l, r;
        for(int i = 1; i <= q; i++){    
            scanf("%s", s);
            if(s[0] == 'Q'){
                scanf("%d%d%d", &l, &r, &x);
                int num = a[cnt] ^ x;
            //    printf("QUERY:%d %d %d
    ", a[l-1], a[r], num);
                printf("%d
    ", query(l, r, num));
                
            }
            else {
                scanf("%d", &x);
                a[++cnt] = a[cnt - 1]^x;
                root[cnt] = Tr.insert(a[cnt], root[cnt - 1]);
        //        printf("ADD:%d
    ", a[cnt]);
            }
            
            
        }
    }
    View Code
  • 相关阅读:
    Spring 事务传播实践分析
    记一次%转义引发的血案
    Springboot+redis 整合
    SpringBoot基础梳理
    MyBatis String类型传递参数注意事项
    SpringBoot填坑系列---XML方式配置数据库
    自定义AlertView(Swift)
    iOS开发,最新判断是否是手机号的正则表达式
    iOS开发 UILabel实现自适应高宽
    iOS开发笔记--UILabel的相关属性设置
  • 原文地址:https://www.cnblogs.com/EdSheeran/p/9396035.html
Copyright © 2020-2023  润新知