zoukankan      html  css  js  c++  java
  • cf1100f

    题意翻译

    给定(n ( 1 leq n leq 500\,000 ))(a_{idots n}( 0 leq a_i leq 10^6))
    (q( 1 leq q leq 500\,000))个询问:

    给定(l,r ( 1 leq l_i leq r_i leq n))

    求在(a_{ldots r})
    中选取任意个,使得他们的异或和最大。


    前缀线性基的模板题目。
    前缀线性基,就是给定数列(a[]),求出(d[i][62])表示数列中前(i)个数的线性基。
    很明显,(d[i][62])就相当于在(d[i-1][62])中再插入(a[i]),其余的相同。
    这里面,(d[i][j])是由第一个产生(j)位的数产生
    我们要求(l,r)间的异或最大值,我们就应当去掉前(l-1)个对结果产生的影响。
    这时,(d[i][j])中的(j)可能会对(l,r)产生影响。但是产生它的数在(l)之前,所以要消除它的影响。但是在(l,r)之前可能还有数可以产生第(j)位,但是由于已经产生就不再起作用。这时我们发现我们应当记录最后产生第(j)们的数的位置,以此再判断是否可以用它来进行异或。
    所以我们要记录(pos[i][j]),表示前(i)个数的线性基,第(j)位可以由最靠后的第几个数产生。

    (color{red}{代码中比较难理解的就是两个swap();可以这样理解:插入x时,如果发现对应的位已经存在,而且产生它的数的位置比当前位置更靠前,那么两个swap()的作用就是把应当的数替换原来的数,并重新插入原来的数。})


    代码:

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=5e5+10;
    int n,q;
    int sz[maxn];
    int d[maxn][32],pos[maxn][32];
    int cnt;
    void insert(int x)
    {
    	cnt++;
    	for(int i=0;i<32;++i)
    	{
    		d[cnt][i]=d[cnt-1][i];
    		pos[cnt][i]=pos[cnt-1][i];
    	}
    	int p=cnt;
    	for(int i=31;i>=0;--i)
    		if(x&(1<<i))
    		{
    			if(d[cnt][i])//如果第i个数已经存在
    			{
    				if(pos[cnt][i]<p)//且产生它的数比当前位置更靠前
    				{//用当前x替代原来的数,当然也更新位置
    					swap(d[cnt][i],x);
    					swap(pos[cnt][i],p);
    				}
    				x^=d[cnt][i];//重新插入
    			}
    			else
    			{
    				d[cnt][i]=x;
    				pos[cnt][i]=p;
    				break;
    			}
    		}
    }
    int main()
    {
    	scanf("%d",&n);
    	for(int i=1;i<=n;++i)
    	{
    		scanf("%d",sz+i);
    		insert(sz[i]);
    	}
    	scanf("%d",&q);
    	int l,r;
    	while(q--)
    	{
    		scanf("%d%d",&l,&r);
    		int ans=0;
    		for(int i=31;i>=0;--i)
    		{
    			if(pos[r][i]<l)continue;
    			if((ans^d[r][i])>ans)ans=ans^d[r][i];
    		}
    		printf("%d
    ",ans);
    	}
    	return 0;
    }
    
  • 相关阅读:
    20191024-1 每周例行报告
    20191017-1 每周例行报告
    20191010-2 每周例行报告
    梁梦瑶 20190919-4 单元测试
    交换机配置VLAN Cisco packet
    20191128-1 总结
    20191121-1 每周例行报告
    20191114-1 每周例行报告
    对组内成员的感谢博客
    每周例行报告
  • 原文地址:https://www.cnblogs.com/gryzy/p/15110215.html
Copyright © 2011-2022 走看看