• 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;
    }
    

      

    自己还是太辣鸡了
  • 相关阅读:
    U盘出现大量乱码文件,并且不能彻底删除
    使用命令生成配置文件
    input只读属性readonly和disabled的区别
    将sublime添加到鼠标右键
    mysql-front导入数据失败:“在多字节的目标代码页中,没有此 Unicode 字符可以映射到的字符”
    typeof运算符
    react input 设置默认值
    时间格式转换
    去除字符串首尾空格
    ES6基础知识汇总
  • 原文地址:https://www.cnblogs.com/zzyer/p/8610166.html
Copyright © 2020-2023  润新知