• [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;
    }
    
  • 相关阅读:
    人人都是 Serverless 架构师 | 现代化 Web 应用开发实战
    KubeDL HostNetwork:加速分布式训练通信效率
    独家下载!阿里云云原生携 10+ 技术专家带来《云原生与云未来的新可能》
    国内唯一!阿里云容器服务进入 Forrester 领导者象限
    函数abs的隐式声明 gcc5.1.0 Implicit declaration of function abs gcc5.1.0
    Vue Design Patterns All In One
    linux 中 tar.lzma 文件的解压、压缩
    linux 中删除除第一次匹配特定字符串所在行之外的所有行
    linux 系统中输出匹配特定字符至末尾的行
    根据位点的物理位置、重组率计算遗传距离
  • 原文地址:https://www.cnblogs.com/wxjor/p/9541161.html
Copyright © 2020-2023  润新知