• [P4735] 最大异或和


    Description

    给定一个非负整数序列 ({a}),初始长度为 (n)

    (m) 个操作,有以下两种操作类型:

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

    Solution

    即求 (s[p-1] oplus (sum oplus x)) 的最大值,很容易想到可持久化 0-1 Trie

    有点卡常

    #include <bits/stdc++.h>
    using namespace std;
    
    const int N = 15000005;
    const int lgn = 23;
    
    int ind;
    int ch[N][2],siz[N],head[N];
    int n,m,a[N],s[N],t1,t2,t3,sum;
    char op[3];
    
    void insert(int x) {
        //cout<<"insert "<<x<<" by "<<n<<endl;
        head[n]=++ind;
        int p=ind,q=head[n-1];
        ch[p][0]=ch[q][0];
        ch[p][1]=ch[q][1];
        siz[p]=siz[q]+1;
        //cout<<p<<","<<q<<endl;
        for(int i=lgn;i>=0;--i) {
            int t=(x>>i)&1;
            ch[p][t]=++ind;
            p=ind;
            q=ch[q][t];
            ch[p][0]=ch[q][0];
            ch[p][1]=ch[q][1];
            siz[p]=siz[q]+1;
            //cout<<p<<","<<q<<endl;
        }
    }
    
    int query(int l,int r,int x) {
        //cout<<"query "<<l<<","<<r<<" "<<x<<endl;
        int p=head[r-1],q=l>1?head[l-2]:0;
        int ans=0;
        for(int i=lgn;i>=0;--i) {
            int t=(x>>i)&1;
            if(siz[ch[p][!t]]-siz[ch[q][!t]]) {
                p=ch[p][!t];
                q=ch[q][!t];
                ans|=1<<i;
            }
            else {
                p=ch[p][t];
                q=ch[q][t];
            }
        }
        return ans;
    }
    
    signed main() {
        ios::sync_with_stdio(false);
        int _n;
        scanf("%d%d",&_n,&m);
        insert(0);
        for(int i=1;i<=_n;i++) {
            ++n;
            scanf("%d",a+i);
            s[i]=s[i-1]^a[i];
            insert(s[i]);
            //8print();
        }
        sum=s[n];
        for(int i=1;i<=m;i++) {
            scanf("%s",op);
            if(op[0]=='A') {
                scanf("%d",&t1);
                a[++n]=t1;
                s[n]=s[n-1]^a[n];
                insert(s[n]);
                sum=s[n];
            }
            else {
                scanf("%d%d%d",&t1,&t2,&t3);
                printf("%d
    ",query(t1,t2,t3^sum));
            }
        }
    }
    
    
  • 相关阅读:
    golang/windows如何删除只读属性文件
    golang/TLS 采坑
    gsweb —— 理解HTTP协议
    gsweb —— 自己动手用golang写WEB框架
    Scala冒泡排序、快排、归并
    Hadoop自动化部署脚本
    大数据学习笔记
    vim键盘图
    什么是回调或高级函数?
    使用CSS表达式去除超链接的虚框的一些方法
  • 原文地址:https://www.cnblogs.com/mollnn/p/13196335.html
Copyright © 2020-2023  润新知