• [BZOJ4184] shallot


    [BZOJ4184] shallot

    Description

    小苗去市场上买了一捆小葱苗,她突然一时兴起,于是她在每颗小葱苗上写上一个数字,然后把小葱叫过来玩游戏。每个时刻她会给小葱一颗小葱苗或者是从小葱手里拿走一颗小葱苗,并且让小葱从自己手中的小葱苗里选出一些小葱苗使得选出的小葱苗上的数字的异或和最大。这种小问题对于小葱来说当然不在话下,但是他的身边没有电脑,于是他打电话给同为Oi选手的你,你能帮帮他吗?你只需要输出最大的异或和即可,若小葱手中没有小葱苗则输出0。

    Input

    第一行一个正整数n表示总时间;第二行n个整数a1,a2...an,若ai大于0代表给了小葱一颗数字为ai的小葱苗,否则代表从小葱手中拿走一颗数字为-ai的小葱苗。

    Output

    输出共n行,每行一个整数代表第i个时刻的最大异或和。

    Sample Input

    6
    1 2 3 4 -2 -3

    Sample Output

    1
    3
    3
    7
    7
    5

    试题分析

    线性基显然无法带删。
    那么我们考虑可以令这题的操作变成只加不删的数据结构,线段树就可以做到。
    按照时间顺序建线段树维护线性基即可。
    线性基要用vector才能卡过去。

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<vector>
    //#include<cmath>
    #include<algorithm>
     
    using namespace std;
    inline int read(){
        int x=0,f=1; char c=getchar();
        for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
        for(;isdigit(c);c=getchar()) x=x*10+c-'0';
        return x*f;
    }
    const int INF = 2147483600;
    const int MAXN = 500010;
     
    int N;
    struct qe{
        int x,tim;
    }a[MAXN+1],b[MAXN+1];
    struct data{
        int u,v,val;
    }in[MAXN+1];
     
    bool cmp(qe a,qe b){if(a.x!=b.x) return a.x<b.x; return a.tim<b.tim;}
    int A,D; vector<int> vec[MAXN<<2]; int sz;
    bool vis[MAXN+1];
     
    inline void Add(int rt,int x){
        for(int i=0;i<vec[rt].size();i++) if((x^vec[rt][i])<x) x^=vec[rt][i];
        if(x){ vec[rt].push_back(x);
            for(int i=vec[rt].size()-1;i;i--) if(vec[rt][i]>vec[rt][i-1]) swap(vec[rt][i],vec[rt][i-1]);
        } return ;
    }
    inline void update(int rt,int s){
        for(int i=0;i<vec[s].size();i++) Add(rt,vec[s][i]); return ;
    }
    inline void insert(int rt,int l,int r,int L,int R,int x){
        if(L<=l&&R>=r){Add(rt,x); return ;} int mid=(l+r)>>1;
        if(L<=mid) insert(rt<<1,l,mid,L,R,x);
        if(R>mid) insert(rt<<1|1,mid+1,r,L,R,x);
    }
    inline void Query(int rt,int l,int r,vector<int> v){
        for(int j=0;j<vec[rt].size();j++){
            int x=vec[rt][j];
            for(int i=0;i<v.size();i++) if((x^v[i])<x) x^=v[i];
                if(x){ v.push_back(x);
                for(int i=v.size()-1;i;i--) if(v[i]>v[i-1]) swap(v[i],v[i-1]);
            }
        }
        if(l==r){ 
            int ret=0;
            for(int j=0;j<v.size();j++) if((ret^v[j])>ret) ret^=v[j];//cout<<ret<<" "<<(ret^c[0][j])<<endl;
            printf("%d
    ",ret);return ;
        } 
        int mid=(l+r)>>1; Query(rt<<1,l,mid,v);
        Query(rt<<1|1,mid+1,r,v); 
        return ;
    }
     
    int main(){
        //freopen(".in","r",stdin);
        //freopen(".out","w",stdout);
        N=read(); int j=1;
        for(int i=1;i<=N;i++){
            int x=read();
            if(x>0) a[++A].x=x,a[A].tim=i;
            else b[++D].x=-x,b[D].tim=i;
        } sort(a+1,a+A+1,cmp); sort(b+1,b+D+1,cmp);
        for(int i=1;i<=D;i++){
            while(a[j].x<b[i].x) ++j;
            in[++sz].u=a[j].tim; in[sz].val=a[j].x;
            in[sz].v=b[i].tim; vis[j]=true; ++j;
        } for(int i=1;i<=A;i++) 
            if(!vis[i]) in[++sz].u=a[i].tim,in[sz].v=N+1,in[sz].val=a[i].x;
        for(int i=1;i<=sz;i++)
            insert(1,1,N,in[i].u,in[i].v-1,in[i].val);
        vector<int> v;
        Query(1,1,N,v);
        return 0;
    }
    
  • 相关阅读:
    Generator函数执行器-co函数库源码解析
    前端解读Webview
    javascript设计模式详解之策略模式
    javascript设计模式详解之命令模式
    【VBA】标准Sub/Function定义,带ScreenUpdating、On Error GoTo
    【VBA】全局数组定义
    【VBA】全局常量定义
    调试Java代码(Eclipse)汇总
    为Eclipse添加反编译插件,更好的调试
    Eclipse图标含义
  • 原文地址:https://www.cnblogs.com/wxjor/p/9541161.html
Copyright © 2020-2023  润新知