zoukankan      html  css  js  c++  java
  • bzoj 4184: shallot【线性基+时间线段树】

    学到了线段树新姿势!
    先离线读入,根据时间建一棵线段树,每个节点上开一个vector存这个区间内存在的数(使用map来记录每个数出现的一段时间),然后在线段树上dfs,到叶子节点就计算答案。
    注意!!从父节点带下来的线性基数组一定要放在函数里传给子节点!全局变量就会多出好多东西!这个其实是常识吧然而我蠢...

    #include<iostream>
    #include<cstdio>
    #include<vector>
    #include<map>
    using namespace std;
    const int N=500005;
    int n,ans[N],s=(1<<30)-1;
    struct qwe
    {
    	int l,r;
    	vector<int>a;
    }t[N<<2];
    struct qw
    {
    	int a[35];
    }la;
    map<int,int>mp;
    int read()
    {
    	int r=0,f=1;
    	char p=getchar();
    	while(p>'9'||p<'0')
    	{
    		if(p=='-')
    			f=-1;
    		p=getchar();
    	}
    	while(p>='0'&&p<='9')
    	{
    		r=r*10+p-48;
    		p=getchar();
    	}
    	return r*f;
    }
    void build(int ro,int l,int r)
    {
    	t[ro].l=l,t[ro].r=r;
    	if(l==r)
    		return;
    	int mid=(l+r)>>1;
    	build(ro<<1,l,mid);
    	build(ro<<1|1,mid+1,r);
    }
    void update(int ro,int l,int r,int x)
    {
    	if(t[ro].l==l&&t[ro].r==r)
    	{
    		t[ro].a.push_back(x);
    		return;
    	}
    	int mid=(t[ro].l+t[ro].r)>>1;
    	if(r<=mid)
    		update(ro<<1,l,r,x);
    	else if(l>mid)
    		update(ro<<1|1,l,r,x);
    	else
    	{
    		update(ro<<1,l,mid,x);
    		update(ro<<1|1,mid+1,r,x);
    	}
    }
    void charu(int x,qw &b)
    {
    	for(int i=30;i>=0;i--)
    		if(x>>i)
    		{
    			if(!b.a[i])
    			{
    				b.a[i]=x;
    				return;
    			}
    			x^=b.a[i];
    		}
    }
    int clc(qw b)
    {
    	int re=0;
    	for(int i=30;i>=0;i--)
    		if((re^b.a[i])>re)
    			re^=b.a[i];
    	return re;
    }
    void dfs(int ro,qw la)
    {
    	for(int i=0;i<t[ro].a.size();i++)
    		charu(t[ro].a[i],la);
    	if(t[ro].l==t[ro].r)
    	{
    		ans[t[ro].l]=clc(la);
    		return;
    	}
    	dfs(ro<<1,la);
    	dfs(ro<<1|1,la);
    }
    int main()
    {
    	n=read();
    	build(1,1,n);//cout<<"OK"<<endl;
    	for(int i=1;i<=n;i++)
    	{
    		int x=read();
    		mp[x]=i;
    		if(x>0)
    			s=min(s,x);
    	}
    	for(map<int,int>::iterator it=mp.find(s);it!=mp.end();it++)
    	{
    		int x=it->first,l=mp[x],r=(mp.find(-x)!=mp.end())?mp[-x]-1:n;
    		update(1,l,r,x);
    	}
    	dfs(1,la);
    	for(int i=1;i<=n;i++)
    		printf("%d
    ",ans[i]);
    	return 0;
    }
    
  • 相关阅读:
    window端口被占用
    webstorm中关闭烦人Eslint语法检查
    STM32 printf 函数原型
    Memset、Memcpy、Strcpy 的作用和区别(转)
    SMD贴片元件的封装尺寸(转)
    Windows Phone开发工具初体验(转载)
    Open Cell(转载)
    标题:常用贴片元件封装(转载)
    关于TV Dongle的功能设计和思考【图】(转载)
    图片预览加上传遇到的一系列问题
  • 原文地址:https://www.cnblogs.com/lokiii/p/8551662.html
Copyright © 2011-2022 走看看