zoukankan      html  css  js  c++  java
  • 最大异或和(xor)

    最大异或和(xor)

    题目描述

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

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

    1、A x:添加操作,表示在序列末尾添加一个数x,序列的长度N+1。

    2、Q l r x:询问操作,你需要找到一个位置p,满足l<=p<=r,使得:

    a[p] xor a[p+1] xor ... xor a[N] xor x 最大,输出最大是多少。

    输入

    第一行包含两个整数N,M,含义如问题描述所示。

    第二行包含N个非负整数,表示初始的序列A。

     

    接下来M行,每行描述一个操作,格式如题面所述。

     

    输出

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

     

    样例输入

    5 5
    2 6 4 3 6 
    A 1
    Q 3 5 4
    A 4
    Q 5 7 0
    Q 3 6 6
    

    样例输出

    4
    5
    6
    

    提示

    本题共有10个测试点,每个测试点10分。

    对于测试点1-2,N,M<=5。

    对于测试点3-7,N,M<=80000。

    对于测试点8-10,N,M<=300000。

    其中测试点1, 3, 5, 7, 9保证没有修改操作。

    对于100%的数据,0<=a[i]<=10^7。


    solution

     考虑异或满足前缀相减。

    答案=1~an~x的异或和异或1~i的异或和

     前一部分是定值。

    后一部分,我们对于每一个前缀都加进trie树,在trie上贪心即可。

    建议写递归写法,注意边界。

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstdlib>
     4 #include<cstring>
     5 #include<algorithm>
     6 #include<cmath>
     7 using namespace std;
     8 int n,m,rt[600005],now,cnt;
     9 struct trie{
    10     int ch[2],v;
    11 }tr[600005*26];
    12 void ins(int k,int la,int v){
    13     for(int i=25;i>=0;i--){
    14         tr[k].v=tr[la].v+1;
    15         bool t=((v&(1<<i))>0);
    16         tr[k].ch[!t]=tr[la].ch[!t];
    17         tr[k].ch[t]=++cnt;
    18         k=tr[k].ch[t],la=tr[la].ch[t];
    19     }
    20     tr[k].v=tr[la].v+1;
    21 }
    22 int ask(int k,int la,int v){
    23     int ans=0;
    24     for(int i=25;i>=0;i--){
    25         bool t=((v&(1<<i))>0);t=(!t);
    26         int s1=tr[k].ch[t],s2=tr[la].ch[t];
    27         if(tr[s1].v>tr[s2].v){
    28             ans+=(1<<i);k=s1;la=s2;
    29         }
    30         else{
    31             k=tr[k].ch[!t],la=tr[la].ch[!t];
    32         }
    33     }
    34     return ans;
    35 }
    36 int main()
    37 {
    38     cin>>n>>m;
    39     for(int i=1,t;i<=n;i++){
    40         scanf("%d",&t);
    41         rt[i]=++cnt;
    42         now^=t;ins(rt[i],rt[i-1],now);
    43     }
    44     int rn=n;
    45     for(int i=1,t,a,b;i<=m;i++){
    46         char c;scanf(" %c",&c);
    47         if(c=='A'){
    48             scanf("%d",&t);rn++;rt[rn]=++cnt;
    49             now^=t;ins(rt[rn],rt[rn-1],now);
    50         }
    51         else {
    52             scanf("%d%d%d",&a,&b,&t);t^=now;
    53             if(b==1)printf("%d
    ",t);
    54             else {
    55                 //cout<<rt[b-1]<<' '<<rt[a-2]<<endl;
    56                 printf("%d
    ",ask(rt[b-1],a-2>0?rt[a-2]:0,t));   
    57             }
    58         }
    59     }
    60     return 0;
    61 }
    View Code
  • 相关阅读:
    前端路由hash、history原理及简单的实践下
    nginx缓存配置及开启gzip压缩
    koa2基于stream(流)进行文件上传和下载
    理解nodejs中的stream(流)
    理解http浏览器的协商缓存和强制缓存
    Nginx中的Rewrite的重定向配置与实践
    Redis入门---字符串类型
    Redis报错 Server started, Redis version 3.2.13 Can't handle RDB format version 9 Fatal error loading the DB: Invalid argument. Exiting.
    redis 基本原理及安装
    Go语言之高级篇beego框架之Controller
  • 原文地址:https://www.cnblogs.com/liankewei/p/10384305.html
Copyright © 2011-2022 走看看