zoukankan      html  css  js  c++  java
  • P4735 最大异或和

    题目链接

    题目描述

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

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

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

    Q l r x:询问操作,你需要找到一个位置p,满足l≤p≤r,使得: a[p]⊕a[p+1]⊕...⊕a[N]⊕x 最大,输出最大是多少。

    输入输出格式

    输入格式:

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

    输出格式:

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

    输入输出样例

    输入样例#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 #include<iostream>
      2 #include<string>
      3 #include<cstdio>
      4 #include<cmath>
      5 #include<cstring>
      6 #include<map>
      7 #include<algorithm>
      8 #include<stack>
      9 #include<queue>
     10 #include<vector>
     11 #define maxn 600005
     12 using namespace std;
     13 
     14 inline int read()
     15 {
     16     int x=1,res=0;
     17     char c=getchar();
     18     while(c<'0'||c>'9')
     19     {
     20         if(c=='-')
     21         x=-1;
     22         c=getchar();
     23     }
     24     while(c>='0'&&c<='9')
     25     {
     26         res=res*10+(c-'0');
     27         c=getchar();
     28     }
     29     return res*x;
     30 }
     31 
     32 int n,m,tot,aa;
     33 int last[maxn*24],root[maxn],s[maxn];
     34 int tree[maxn*24][2];
     35 
     36 void trie(int i,int k,int l,int r)
     37 {
     38     if(k<0)
     39     {
     40         last[r]=i;
     41         return;
     42     }
     43     int c=(s[i]>>k)&1;
     44     if(l) tree[r][c^1]=tree[l][c^1];
     45     tree[r][c]=++tot;
     46     trie(i,k-1,tree[l][c],tree[r][c]);
     47     last[r]=max(last[tree[r][0]],last[tree[r][1]]);
     48 }
     49 
     50 int ask(int now,int val,int k,int l)
     51 {
     52     if(k<0) return val^s[last[now]];
     53     int c=val>>k&1;
     54     if(last[tree[now][c^1]]>=l)/*如果以这个点为根的子树上的结点的最大编号 
     55     大于等于l,那么这个结点就有意义,否则,这个结点就没有任何意义*/
     56     {
     57         return ask(tree[now][c^1],val,k-1,l);
     58     }
     59     else
     60     {
     61         return ask(tree[now][c],val,k-1,l);
     62     }
     63 }
     64 
     65 int main()
     66 {
     67     n=read();m=read();
     68     last[0]=-100;/*0号点其实就是trie树上不存在的点,之所以清为负数而不是
     69     0,这是因为如果询问的区间的l是1,那么根据我们会把所有last的值>=0(l-1)
     70     的数计算进去,这样如果不清为负数,那么trie树上没有的点我们也会错误的
     71     计算进去,所以last一定要清为负数。 
     72     */
     73     root[0]=++tot;/*这个根节点标记为1是为了和不在trie树上的点区分开 */ 
     74     trie(0,23,0,1);//先构造一个全0的trie树 
     75     for(int i=1;i<=n;i++)
     76     {
     77         aa=read();
     78         s[i]=s[i-1]^aa;
     79         root[i]=++tot;
     80         trie(i,23,root[i-1],root[i]);
     81     }
     82     for(int i=1;i<=m;i++)
     83     {
     84         char c;
     85         scanf("%s",&c);
     86         if(c=='A')
     87         {
     88             aa=read();
     89             root[++n]=++tot;
     90             s[n]=s[n-1]^aa;
     91             trie(n,23,root[n-1],root[n]);
     92         }
     93         else
     94         {
     95             int l,r,x;
     96             l=read();r=read();x=read();
     97             printf("%d
    ",ask(root[r-1],s[n]^x,23,l-1));
     98         }
     99     }
    100 }
    View Code
    
    
  • 相关阅读:
    Java异常的分类
    Java SE 6 新特性: Java DB 和 JDBC 4.0
    Java SE 6 新特性: 对脚本语言的支持
    面向对象开发方法优点
    RocketMQ之八:水平扩展及负载均衡详解
    Bluetooth 4.0之Android 解说
    iOS截取视频缩略图的两种方法
    Java NIO Buffer
    spark 启动job的流程分析
    C语言堆内存管理上出现的问题,内存泄露,野指针使用,非法释放指针
  • 原文地址:https://www.cnblogs.com/snowy2002/p/10479564.html
Copyright © 2011-2022 走看看