zoukankan      html  css  js  c++  java
  • BZOJ 4568 [Scoi2016]幸运数字

     题解:

    倍增维护线性基

    线性基合并
    注意,少传参,浪费时间

    //少传参 
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    typedef long long Lint;
    const int maxn=20009;
    const int u=61;
    
    int n,TT;
    Lint val[maxn];
    
    struct BS{
    	Lint a[u+2];
    	BS(){
    		memset(a,0,sizeof(a));
    	}
    	void Clea(){
    		memset(a,0,sizeof(a));
    	}
    }g[maxn][15],T;//u=14
    int f[maxn][15]={0};
    int dep[maxn]={0};
    
    void MerNum(Lint x){
    	for(int j=u;j>=1;--j){
    		if(!(x&(1LL<<(j-1))))continue;
    		if(T.a[j]){
    			x^=T.a[j];
    		}else{
    			T.a[j]=x;break;
    		}
    	}
    }
    void MerBS(BS B){
    	for(int j=u;j>=1;--j){
    		if(B.a[j])MerNum(B.a[j]);
    	}
    }
    
    int cntedge=0;
    int head[maxn]={0};
    int to[maxn<<1],nex[maxn<<1];
    void Addedge(int x,int y){
    	nex[++cntedge]=head[x];
    	to[cntedge]=y;
    	head[x]=cntedge;
    }
    
    void Dfs(int x,int fa){
    	f[x][0]=fa;
    	dep[x]=dep[fa]+1;
    	for(int i=head[x];i;i=nex[i]){
    		if(to[i]==fa)continue;
    		Dfs(to[i],x);
    	}
    }
    
    void LCAinit(){
    	for(int i=1;i<=n;++i){
    		T.Clea();
    		MerNum(val[i]);
    		MerNum(val[f[i][0]]);
    		g[i][0]=T;
    	}
    	for(int j=1;j<=14;++j){
    		for(int i=1;i<=n;++i){
    			f[i][j]=f[f[i][j-1]][j-1];
    			if(f[i][j]){
    				T.Clea();
    				MerBS(g[i][j-1]);MerBS(g[f[i][j-1]][j-1]);
    				g[i][j]=T;
    			}
    		}
    	}
    }
    Lint Getans(){
    	Lint ret=0;
    	for(int j=u;j>=1;--j){
    		if((ret^T.a[j])>ret)ret=(ret^T.a[j]);
    	}
    	return ret;
    }
    
    Lint Querymax(int u,int v){
    	if(u==v)return val[u];
    	T.Clea();
    	if(dep[u]<dep[v])swap(u,v);
    	for(int j=14;j>=0;--j){
    		if(dep[f[u][j]]>=dep[v]){
    			MerBS(g[u][j]);
    			u=f[u][j];
    		}
    	}
    	if(u==v){
    		return Getans();
    	}
    	for(int j=14;j>=0;--j){
    		if(f[u][j]!=f[v][j]){
    			MerBS(g[u][j]);
    			MerBS(g[v][j]);
    			u=f[u][j];v=f[v][j];
    		}
    	}
    	MerNum(val[u]);
    	MerNum(val[v]);
    	MerNum(val[f[u][0]]);
    	return Getans();
    }
    
    int main(){
    	scanf("%d%d",&n,&TT);
    	for(int i=1;i<=n;++i)scanf("%lld",&val[i]);
    	for(int i=1;i<=n-1;++i){
    		int x,y;scanf("%d%d",&x,&y);
    		Addedge(x,y);
    		Addedge(y,x);
    	}
    	Dfs(1,0);
    	LCAinit();
    	while(TT--){
    		int x,y;
    		scanf("%d%d",&x,&y);
    		printf("%lld
    ",Querymax(x,y));
    	}
    	return 0;
    }
    

      

    自己还是太辣鸡了
  • 相关阅读:
    数据结构总结(UPDATING......)
    课件例题4.11,4.12
    Luogu P1525 关押罪犯
    Luogu P1540 机器翻译
    Luogu P1313 计算系数
    Luogu P1311 选择客栈
    Luogu P1519 穿越栅栏 Overfencing
    Luogu P2863 [USACO06JAN]牛的舞会The Cow Prom
    Tarjan学习笔记
    Luogu P3393 逃离僵尸岛
  • 原文地址:https://www.cnblogs.com/zzyer/p/8610166.html
Copyright © 2011-2022 走看看