• Bzoj3261 最大异或和


    Time Limit: 10 Sec  Memory Limit: 512 MB
    Submit: 1769  Solved: 747

    Description

         

    给定一个非负整数序列 {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 最大,输出最大是多少。  

    Input

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

    Output

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

    Sample Input

    5 5
    2 6 4 3 6
    A 1
    Q 3 5 4
    A 4
    Q 5 7 0
    Q 3 6 6
    对于测试点 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。

    Sample Output

    4
    5
    6

    HINT

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

    字符串 贪心 可持久化trie树

    trie树也能可持久化,写法和主席树差不多,快来试试吧!

    搞一个异或前缀和sum[],那么目标就是在区间内找到一个p,使得sum[p-1]^x^sum[n]最大

    为了处理p在开头的情况,在最前面补一个0,所有数下标右移一位。

    把每个数看成一个从高位到低位的二进制串,添加到可持久化trie树里

    建好trie树以后,从根开始贪心走和当前这位相反的边即可。

     1 /*by SilverN*/
     2 #include<iostream>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<cstdio>
     6 #include<cmath>
     7 #include<vector>
     8 using namespace std;
     9 const int mxn=300010;
    10 int read(){
    11     int x=0,f=1;char ch=getchar();
    12     while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    13     while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
    14     return x*f;
    15 }
    16 int rot[mxn<<1];
    17 struct Trie{
    18     int t[mxn*50][2];
    19     int id[mxn*50],cnt;
    20     void insert(int v,int y,int rt){
    21         rot[rt]=++cnt;
    22         int now=cnt;
    23         id[now]=rt;
    24         for(int i=23;i>=0;i--){
    25             int j=(v>>i)&1;
    26             t[now][j^1]=t[y][j^1];//继承旧树 
    27             t[now][j]=++cnt;//建立新枝 
    28             now=t[now][j];
    29             id[now]=rt; 
    30             y=t[y][j];
    31         }
    32         return;
    33     }
    34     int query(int l,int r,int val){
    35         int now=rot[r];
    36         int res=0;
    37         for(int i=23;i>=0;i--){
    38             if(id[now]<l)break;
    39             int j=(val>>i)&1;//val的值 
    40             if(id[t[now][j^1]]>=l)res|=(1<<i),j^=1;//贪心,能异则异 
    41             now=t[now][j];
    42         }
    43         return res;
    44     }
    45 }tr;
    46 int n,m;
    47 int a[mxn],smm=0;
    48 int main(){
    49     int i,j;
    50     n=read()+1;m=read();
    51     a[1]=0;
    52     for(i=2;i<=n;i++)a[i]=read();
    53     for(i=1;i<=n;i++){
    54         smm^=a[i];
    55         tr.insert(smm,rot[i-1],i);
    56     }
    57     char op[2];
    58     int l,r,x;
    59     while(m--){
    60         scanf("%s",op);
    61         if(op[0]=='A'){
    62             x=read();
    63             smm^=x;
    64             tr.insert(smm,rot[n],n+1);
    65             ++n;
    66         }
    67         else{
    68             l=read();r=read();x=read();
    69             int ans=tr.query(l,r,x^smm);
    70             printf("%d
    ",ans);
    71         }
    72     }
    73     return 0;
    74 }
  • 相关阅读:
    WPF Caliburn 学习笔记(五)HelloCaliburn
    MSDN 教程短片 WPF 20(绑定3ObjectDataProvider)
    MSDN 教程短片 WPF 23(3D动画)
    比赛总结一
    HDU3686 Traffic Real Time Query System
    HDU3954 Level up
    EOJ382 Match Maker
    UESTC1565 Smart Typist
    HDU3578 Greedy Tino
    ZOJ1975 The Sierpinski Fractal
  • 原文地址:https://www.cnblogs.com/SilverNebula/p/6771217.html
Copyright © 2020-2023  润新知