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

    3261: 最大异或和

    Time Limit: 10 Sec  Memory Limit: 512 MB
    Submit: 1369  Solved: 578
    [Submit][Status][Discuss]

    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行,每行一个整数表示询问的答案。

     
    可持久化trie模版题....
    --------
    hzwer:
    记b[i]为1到i的a的异或和
    则求max(b[p]^b[n]^x) (l-1<=p<=r-1)
     
    每次加点将trie树的这条链的权都+1
    修改当然是新建一个结点(类可持久化线段树)
    然后查询的时候判断一个结点存在,只要做区间减法判权是否非0
    即若sum[r]-sum[l-1]=0则该结点不存在
    查询的贪心策略略。。。
    实现的时候数列开始加入一个数0会比较好处理
     ---------
     1 #include<bits/stdc++.h>
     2 #define rep(i,l,r) for(int i=l;i<=r;++i)
     3 using namespace std;
     4 const int N=15023333;
     5 int n,m,a[N],two[30],l,r,x,rt[N],b[N],ch[N][2],cnt,sum[N];
     6 char c[50];
     7 int add(int x,int val){
     8     int tmp,y=tmp=++cnt,t;
     9     for(int i=23;i>=0;--i){
    10         ch[y][0]=ch[x][0]; ch[y][1]=ch[x][1];
    11         sum[y]=sum[x]+1;
    12         t=val&two[i]; t>>=i;
    13         x=ch[x][t];
    14         y=ch[y][t]=++cnt;
    15     }
    16     sum[y]=sum[x]+1;
    17     return tmp;
    18 }
    19 inline int que(int l,int r,int val){
    20     int tmp=0,t;
    21     for(int i=23;i>=0;i--){
    22         t=val&two[i]; t>>=i;
    23         if(sum[ch[r][t^1]]-sum[ch[l][t^1]]) tmp+=two[i],r=ch[r][t^1],l=ch[l][t^1];
    24         else r=ch[r][t],l=ch[l][t];
    25     }
    26     return tmp;
    27 }
    28 int main(){
    29     scanf("%d%d",&n,&m);
    30     ++n; rep(i,2,n) scanf("%d",&a[i]);
    31     two[0]=1; rep(i,1,25) two[i]=two[i-1]*2;
    32     rep(i,1,n) b[i]=b[i-1]^a[i],rt[i]=add(rt[i-1],b[i]);
    33     rep(i,1,m){
    34         scanf("%s",c);
    35         if(c[0]=='A') {
    36             ++n;
    37             scanf("%d",&a[n]);
    38             b[n]=b[n-1]^a[n];
    39             rt[n]=add(rt[n-1],b[n]);
    40         }else {
    41             scanf("%d%d%d",&l,&r,&x);
    42             printf("%d
    ",que(rt[l-1],rt[r],b[n]^x));
    43         }
    44     }
    45 }
    View Code
  • 相关阅读:
    if...else if switch分支结构
    Code大蛇丸 腾讯微博 key
    当GridView中的一项被点中的时候显示的背景图片:android:listSelector="@drawable/choose_gridview"
    手机通讯录
    JDOM和XPATH薛谷雨
    修改myEclipse8.5的默认的工作空间
    用JoyToKey使游戏手柄变键盘或鼠标
    在Spring3中,配置DataSource的方法有五种
    Struts+spring使用随机验证码
    项目部署不到tomcat中的原因和解决方法
  • 原文地址:https://www.cnblogs.com/Bloodline/p/5960333.html
Copyright © 2011-2022 走看看