• [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

    比较基础的线段树分治练习题.

    按照修改时间的区间分治.

    维护一个线性基,但是线性基不支持删除元素,于是递归的时候存在栈里就可以了.

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<vector>
    #define mid ((l+r)>>1)
    #define lc (rt<<1)
    #define rc ((rt<<1)|1)
    #define maxn 500005
    using namespace std;
    int cnt,n,len;
    int b[maxn],seq[maxn],nxt[maxn],head[maxn],ans[maxn];
    vector<int> seg[maxn<<2];
    struct number{int x,l,r;}p[maxn];
    struct node
    {
    	int num,base[33];
    	void insert(int x)
    		{
    			if(num==32)return;
    			for(int i=31;~i;i--)
    				if(x&(1<<i))
    				{
    					if(!base[i]){base[i]=x;++num;}
    					x^=base[i];
    				}
    		}
    	int getmax(int x){for(int i=31;~i;i--)x=max(x,x^base[i]);return x;}
    }A;
    void update(int rt,int l,int r,int L,int R,int x)
    {
    	if(l>R||r<L)return;
    	if(L<=l&&r<=R){seg[rt].push_back(x);return;}
    	update(lc,l,mid,L,R,x);update(rc,mid+1,r,L,R,x);
    }
    void divide(int rt,int l,int r,node A)
    {
    	for(int i=seg[rt].size()-1;A.num<32&&~i;i--)A.insert(seg[rt][i]);
    	for(int i=l;i<=r;i++)ans[i]=max(ans[i],A.getmax(0));
    	if(l==r)return;divide(lc,l,mid,A);divide(rc,mid+1,r,A);
    }
    int main()
    {
    	cin>>n;
    	for(int i=1;i<=n;i++)scanf("%d",&seq[i]);
    	for(int i=1;i<=n;i++)b[i]=abs(seq[i]);
    	sort(b+1,b+1+n);len=unique(b+1,b+1+n)-b-1;
    	for(int i=1;i<=n;i++)
    	{
    		if(seq[i]>0)
    		{
    			int u=lower_bound(b+1,b+1+len,seq[i])-b;
    			nxt[++cnt]=head[u];head[u]=cnt;
    			p[cnt]=(number){seq[i],i,n};
    		}
    		else
    		{
    			int u=lower_bound(b+1,b+1+len,-seq[i])-b;
    			int j=head[u];p[j].r=i-1;head[u]=nxt[j];
    		}
    	}
    	for(int i=1;i<=cnt;i++)update(1,1,n,p[i].l,p[i].r,p[i].x);
    	divide(1,1,n,A);
    	for(int i=1;i<=n;i++)printf("%d
    ",ans[i]);
    	return 0;
    }
    
    
  • 相关阅读:
    etl接口测试总结
    LR controller 参数化
    Mysql导入导出命令
    mysql基本命令
    mysql用户管理(新增用户及权限管理)
    源码编译搭建LAMP
    【OpenGL】Shader实例分析(一)-Wave
    仿真树叶飘落效果的实现(精灵旋转、翻转、钟摆运动等综合运用)
    cocos2d-x游戏开发(十四)用shader使图片背景透明
    泰然发布了一系列 OpenGL3.0 的教程,推荐大家参考学习
  • 原文地址:https://www.cnblogs.com/terribleterrible/p/9873321.html
Copyright © 2020-2023  润新知