• BZOJ3261: 最大异或和


    $n leq 300000$的数列支持$m leq 300000$个操作:在末端插入一个数;询问整个数列的所有后缀异或和中$[L,R]$这些后缀异或和,异或上数字$x$后的哪一个最大。数字$leq 1e7$。

    转前缀和,变成$pre_n xor pre_{p-1} xor x,L-1 leq p leq R-1$。在区间里找一个数能异或上某个数最大,干这事需要可持久化Trie。写过主席树的可以直接yy。

     1 #include<stdio.h>
     2 #include<string.h>
     3 //#include<iostream>
     4 #include<algorithm>
     5 using namespace std;
     6 
     7 #define LL long long
     8 int qread()
     9 {
    10     char c; int s=0,t=1; while ((c=getchar())<'0' || c>'9') (c=='-') && (t=-1);
    11     do s=s*10+c-'0'; while ((c=getchar())>='0' && c<='9'); return s*t;
    12 }
    13 
    14 //
    15 
    16 int n,m;
    17 #define maxn 600011
    18 int root[maxn];
    19 struct Trie
    20 {
    21     struct Node{int ls,rs,cnt;}a[maxn*26];
    22     int size;
    23     void insert(int &x,int y,int v)
    24     {
    25         int w=x=++size; a[w].cnt=1;
    26         for (int i=25;~i;i--)
    27         {
    28             int u=(v>>i)&1;
    29             a[w].ls=a[y].ls; a[w].rs=a[y].rs;
    30             if (u) {a[w].rs=++size; w=size; y=a[y].rs;}
    31             else {a[w].ls=++size; w=size; y=a[y].ls;}
    32             a[w].cnt=a[y].cnt+1;
    33         }
    34     }
    35     int query(int x,int y,int v)
    36     {
    37         int ans=0;
    38         for (int i=25;~i;i--)
    39         {
    40             int u=(v>>i)&1;
    41             if (u)
    42             {
    43                 if (a[a[y].ls].cnt>a[a[x].ls].cnt)
    44                 {
    45                     ans|=(1<<i);
    46                     y=a[y].ls; x=a[x].ls;
    47                 }
    48                 else y=a[y].rs,x=a[x].rs;
    49             }
    50             else
    51             {
    52                 if (a[a[y].rs].cnt>a[a[x].rs].cnt)
    53                 {
    54                     ans|=(1<<i);
    55                     y=a[y].rs; x=a[x].rs;
    56                 }
    57                 else y=a[y].ls,x=a[x].ls;
    58             }
    59         }
    60         return ans;
    61     }
    62 }t;
    63 
    64 int a[maxn];
    65 int main()
    66 {
    67     n=qread(); m=qread();
    68     t.insert(root[0],0,0);
    69     for (int i=1,x;i<=n;i++)
    70     {
    71         x=qread(); a[i]=a[i-1]^x;
    72         t.insert(root[i],root[i-1],a[i]);
    73     }
    74     
    75     char c; int x,y,v;
    76     while (m--)
    77     {
    78         while ((c=getchar())!='A' && c!='Q');
    79         if (c=='A')
    80         {
    81             scanf("%d",&v);
    82             n++; a[n]=a[n-1]^v;
    83             t.insert(root[n],root[n-1],a[n]);
    84         }
    85         else
    86         {
    87             scanf("%d%d%d",&x,&y,&v);
    88             printf("%d
    ",t.query(x>1?root[x-2]:0,root[y-1],v^a[n]));
    89         }
    90     }
    91     return 0;
    92 }
    View Code
  • 相关阅读:
    装饰器的加载顺序
    生成器
    迭代器
    有参装饰器与装饰器补充
    无参装饰器
    闭包函数
    函数对象与函数嵌套
    名称空间与作用域
    函数参数补充
    函数参数的使用
  • 原文地址:https://www.cnblogs.com/Blue233333/p/9084487.html
Copyright © 2020-2023  润新知