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

    题解:可持久trie树 类似于可持久化线段树那样 每次更新一个值实质上只更新一条链即可 然后维护前缀异或和 问题转化为求在[l,r]区间内选一个前缀异或和异或上(x^sum[N])最大 然后01字典树贪心即可

    #include <algorithm>
    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <vector>
    #include <stack>
    #include <queue>
    #include <cmath>
    #include <set>
    #include <map>
    #define mp make_pair
    #define pb push_back
    #define pii pair<int,int>
    #define link(x) for(edge *j=h[x];j;j=j->next)
    #define inc(i,l,r) for(int i=l;i<=r;i++)
    #define dec(i,r,l) for(int i=r;i>=l;i--)
    const int MAXN=6e5+10;
    const double eps=1e-8;
    #define ll long long
    using namespace std;
    struct edge{int t,v;edge*next;}e[MAXN<<1],*h[MAXN],*o=e;
    void add(int x,int y,int vul){o->t=y;o->v=vul;o->next=h[x];h[x]=o++;}
    ll read(){
        ll x=0,f=1;char ch=getchar();
        while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
        while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
        return x*f;
    }
    
    
    typedef struct node{
        int l,r,sum;
    }node;
    node d[31*MAXN];
    int cnt,vul,rt[MAXN];
    int a[MAXN],sum[MAXN];
    void insert(int x,int k){
        for(int i=29;i>=0;i--){
            if(k&(1<<i)){
                int t=++cnt;d[t]=d[d[x].r];d[x].r=t;d[t].sum++;
                x=t;
            }
            else{
                int t=++cnt;d[t]=d[d[x].l];d[x].l=t;d[t].sum++;
                x=t;
            }
        }
    }
    int querty(int x,int y,int k){
        int res=0;
        for(int i=29;i>=0;i--){
            if(k&(1<<i)){
                if(d[d[y].l].sum-d[d[x].l].sum)x=d[x].l,y=d[y].l;
                else res+=(1<<i),x=d[x].r,y=d[y].r;
            }
            else{
                if(d[d[y].r].sum-d[d[x].r].sum)res+=(1<<i),x=d[x].r,y=d[y].r;
                else x=d[x].l,y=d[y].l;
            }
        }
        return (res^k);
    }
    int main(){
        int n,m;n=read();m=read();cnt=0;
        sum[0]=0;
        inc(i,1,n)a[i]=read(),sum[i]=a[i]^sum[i-1];
        rt[0]=++cnt;insert(rt[0],0);
        inc(i,1,n+1){
            rt[i]=++cnt;d[rt[i]]=d[rt[i-1]];
            insert(rt[i],sum[i-1]);
        }
        char ch;int l,r,x;int tot=n+1;
        while(m--){
            scanf(" %c",&ch);
            if(ch=='A')x=read(),tot++,sum[tot-1]=sum[tot-2]^x,rt[tot]=++cnt,d[rt[tot]]=d[rt[tot-1]],insert(rt[tot],sum[tot-1]);
            else{
                l=read();r=read();x=read();
                printf("%d
    ",querty(rt[l-1],rt[r],x^sum[tot-1]));
            }
        }
        return 0;
    }
    

     

    3261: 最大异或和

    Time Limit: 10 Sec  Memory Limit: 512 MB
    Submit: 3186  Solved: 1315
    [Submit][Status][Discuss]

    Description

    给定一个非负整数序列{a},初始长度为N。
    有M个操作,有以下两种操作类型:
    1、Ax:添加操作,表示在序列末尾添加一个数x,序列的长度N+1。
    2、Qlrx:询问操作,你需要找到一个位置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保证没有修改操作。
    0<=a[i]<=10^7。

    Sample Output

    4
    5
    6
  • 相关阅读:
    Call KernelIoControl in user space in WINCE6.0
    HOW TO:手工删除OCS在AD中的池和其他属性
    关于新版Windows Server 2003 Administration Tools Pack
    关于SQL2008更新一则
    微软发布3款SQL INJECTION攻击检测工具
    HyperV RTM!
    OCS 2007 聊天记录查看工具 OCSMessage
    CoreConfigurator 图形化的 Server Core 配置管理工具
    OC 2007 ADM 管理模板和Live Meeting 2007 ADM 管理模板发布
    Office Communications Server 2007 R2 即将发布
  • 原文地址:https://www.cnblogs.com/wang9897/p/9718084.html
Copyright © 2011-2022 走看看