zoukankan      html  css  js  c++  java
  • 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

    HINT

     N<=500000,Ai<=2^31-1

    不难发现,题目其实就是要求我们动态维护带插入和删除的线性基。
    我们线段树分治一下,按时间建立线段树,一次插入对应有效的一段时间。
    时间复杂度为O(Nlog^2N)。
    #include<cstdio>
    #include<cctype>
    #include<queue>
    #include<cstring>
    #include<algorithm>
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define dwn(i,s,t) for(int i=s;i>=t;i--)
    #define ren for(int i=first[x];i;i=next[i])
    using namespace std;
    const int BufferSize=1<<16;
    char buffer[BufferSize],*head,*tail;
    inline char Getchar() {
    	if(head==tail) {
    		int l=fread(buffer,1,BufferSize,stdin);
    		tail=(head=buffer)+l;
    	}
    	return *head++;
    }
    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 maxn=500010;
    struct Set {
    	int A[32];
    	Set() {memset(A,0,sizeof(A));}
    	void insert(int val) {
    		dwn(i,30,0) if(val>>i&1) {
    			if(!A[i]) {A[i]=val;break;}
    			val^=A[i];
    		}
    	}
    	int query() {
    		int res=0;
    		dwn(i,30,0) res=max(res,res^A[i]);
    		return res;
    	}
    };
    int n,ls[maxn*2],rs[maxn*2],A[maxn],f[maxn],tmp[maxn],last[maxn];
    int first[maxn*2],next[maxn*20],num[maxn*20],ToT,e,cnt;
    void build(int& o,int l,int r) {
    	o=++ToT;
    	if(l==r) return;
    	int mid=l+r>>1;
    	build(ls[o],l,mid);build(rs[o],mid+1,r);
    }
    void AddQuery(int o,int l,int r,int ql,int qr,int v) {
    	if(ql<=l&&r<=qr) {
    		num[++e]=v;next[e]=first[o];first[o]=e;
    	}
    	else {
    		int mid=l+r>>1;
    		if(ql<=mid) AddQuery(ls[o],l,mid,ql,qr,v);
    		if(qr>mid) AddQuery(rs[o],mid+1,r,ql,qr,v);
    	}
    }
    void solve(int o,int l,int r,Set G) {
    	for(int i=first[o];i;i=next[i]) G.insert(num[i]);
    	if(l==r) printf("%d
    ",G.query());
    	else {
    		int mid=l+r>>1;solve(ls[o],l,mid,G);solve(rs[o],mid+1,r,G);
    	}
    }
    int main() {
    	n=read();int rt=0;
    	rep(i,1,n) tmp[i]=abs(A[i]=read());
    	sort(tmp+1,tmp+n+1);
    	rep(i,1,n) last[i]=n+1;
    	dwn(i,n,1) {
    		int flag=1;
    		if(A[i]<0) flag=-1,A[i]=-A[i];
    		A[i]=lower_bound(tmp+1,tmp+n+1,A[i])-tmp;
    		f[i]=last[A[i]];last[A[i]]=i;
    		A[i]*=flag;
    	}
    	build(rt,1,n);
    	rep(i,1,n) if(A[i]>0) AddQuery(1,1,n,i,f[i]-1,tmp[A[i]]);
    	Set T;solve(1,1,n,T);
    	return 0;
    }
    

      

  • 相关阅读:
    BP神经网络基本原理
    天将降大任于斯人也,必先苦其心志,劳其筋骨,饿其体肤,空乏其身,行拂乱其所为,所以动心忍性,增益其所不能
    LSH算法原理
    数据库索引的作用和长处缺点
    开机黑屏 仅仅显示鼠标 电脑黑屏 仅仅有鼠标 移动 [已成功解决]
    Linux makefile 教程 很具体,且易懂
    银行家算法
    HDU 1757 A Simple Math Problem(矩阵高速幂)
    js中substr与substring的差别
    BackTrack5 (BT5)无线password破解教程之WPA/WPA2-PSK型无线password破解
  • 原文地址:https://www.cnblogs.com/wzj-is-a-juruo/p/5378867.html
Copyright © 2011-2022 走看看