BZOJ 4184: shallot 线性基+线段树分治

复习一下线性基 ~ 

code:

#include <cmath>
#include <vector> 
#include <cstdio>  
#include <string> 
#include <cstring>   
#include <algorithm>    
#define N 500008  
#define ll long long  
#define lson now<<1
#define rson now<<1|1
using namespace std;   
namespace IO 
{ 
    void setIO(string s) 
    {
        string in=s+".in"; 
        string out=s+".out"; 
        freopen(in.c_str(),"r",stdin); 
        freopen(out.c_str(),"w",stdout);  
    }
};         
int bin[32],a[N],S[N],n,tot,edges;   
int hd[N],to[N],nex[N];   
struct node 
{
    int l,r,x;    
    node(int l=0,int r=0,int x=0):l(l),r(r),x(x){}  
}p[N];  
vector<node>sg[N<<2];   
struct Base
{  
    int p[32],nm;           
    void insert(int x) 
    {
        for(int i=30;i>=0;--i) 
        {
            if(x&bin[i]) 
            {
                if(p[i]) x^=p[i];     
                else { p[i]=x; break; }  
            }
        } 
    }               
    int query(int x) { for(int i=30;i>=0;--i) if((x^p[i])>x) x^=p[i]; return x; }         
}tmp;   
void update(int l,int r,int now,int L,int R,node e) 
{  
    if(l>=L&&r<=R)  { sg[now].push_back(e);    return; } 
    int mid=(l+r)>>1;  
    if(L<=mid)  update(l,mid,lson,L,R,e);       
    if(R>mid)   update(mid+1,r,rson,L,R,e);   
} 
void dfs(int l,int r,int now,Base G) 
{ 
    for(int i=0;i<sg[now].size();++i) G.insert(sg[now][i].x);   
    if(l==r) { printf("%d\n",G.query(0));   return; }    
    int mid=(l+r)>>1;     
    dfs(l,mid,lson,G),dfs(mid+1,r,rson,G);    
}
int main() 
{  
    // IO::setIO("input");  
    int i,j,len; 
    scanf("%d",&n);  
    for(i=0;i<=30;++i) bin[i]=1<<i;      
    for(i=1;i<=n;++i) scanf("%d",&a[i]);    
    for(i=1;i<=n;++i) S[i]=abs(a[i]);  
    sort(S+1,S+1+n);  
    for(i=1;i<=n;++i) 
    {
        if(a[i]>0) 
        { 
            int x=lower_bound(S+1,S+1+n,a[i])-S;   
            nex[++edges]=hd[x],hd[x]=edges,p[edges]=node(i,n,a[i]);      
        } 
        else 
        {      
            int x=lower_bound(S+1,S+1+n,-a[i])-S;     
            p[hd[x]].r=i-1,hd[x]=nex[hd[x]];   
        }   
    }              
    for(i=1;i<=edges;++i) update(1,n,1,p[i].l,p[i].r,p[i]);        
    dfs(1,n,1,tmp);   
    return 0;                 
}

  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值