• 【 [SCOI2016]幸运数字】


    P3292 [SCOI2016]幸运数字

    想法

    倍增加上线性基就行惹
    线性基的合并可以通过把一个线性基的元素插入到另一个里实现

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define ll long long
    #define N 20005
    #define M 40005
    
    ll cnt,v[N],G[N][21][62],head[N],dep[N];
    ll fa[N][21],ans[62];
    
    struct P{
    	int to,next;
    }e[M];
    
    void add(int x,int y){
    	e[++cnt].to = y;
    	e[cnt].next = head[x];
    	head[x] = cnt;
    }
    
    void insert(ll *a,ll val){
    	for(int i = 61;i >= 0;--i){
    		if((val >> i) & 1){
    			if(!a[i]){
    				a[i] = val;
    				break;
    			}
    			val ^= a[i];
    		}
    	}
    }
    
    void Merge(ll *a,ll *b){
    	for(int i = 61;i >= 0;--i){
    		if(b[i])
    		insert(a,b[i]);
    	}
    }
    
    void dfs(ll u,ll f){
    	fa[u][0] = f;
    	dep[u] = dep[f] + 1;
    	for(int i = head[u];i;i = e[i].next){
    		ll v = e[i].to;
    		if(v == f)
    		continue;
    		dfs(v,u);
    	}
    }
    
    ll n,q;
    
    void getlca(){
    	for(int j = 1;j <= 20;++j)
    	for(int i = 1;i <= n;++i){
    		fa[i][j] = fa[fa[i][j - 1]][j - 1];
    		std::memcpy(G[i][j],G[i][j - 1],sizeof(G[i][j - 1]));
    		Merge(G[i][j],G[fa[i][j - 1]][j - 1]);
    	}
    }
    
    void lca(ll x,ll y){
    	if(dep[x] < dep[y])
    	std::swap(x,y);
    	for(int i = 20;i >= 0;--i){
    		if(dep[fa[x][i]] >= dep[y]){
    			Merge(ans,G[x][i]);
    			x = fa[x][i];
    		}
    	}
    	if(x == y){
    		Merge(ans,G[x][0]);
    		return;
    	}
    	for(int i = 20;i >= 0;--i){
    		if(fa[x][i] != fa[y][i]){
    			Merge(ans,G[x][i]);
    			Merge(ans,G[y][i]);
    			x = fa[x][i];
    			y = fa[y][i];
    		}
    	}
    	Merge(ans,G[x][0]),Merge(ans,G[y][0]),Merge(ans,G[fa[x][0]][0]);
    	return;
    }
    
    inline ll read(){
    	ll ans = 0,f = 1;
    	char a = getchar();
    	while(a < '0' && a > '9' && (a != '-'))
    	a = getchar();
    	if(a == '-')
    	f = -1,a = getchar();
    	while(a <= '9' && a >= '0'){
    		ans = (ans << 3) + (ans << 1) + (a - '0'),a = getchar();
    	}
    	return ans * f;
    }
    
    int main(){
    	n = read(),q = read();
    	for(int i = 1;i <= n;++i)
    	insert(G[i][0],read());
    	for(int i = 1;i <= n - 1;++i){
    		ll x = read(),y = read();
    		add(x,y);
    		add(y,x);
    	}
    	dfs(1,0);
    	getlca();
    	for(int i = 1;i <= q;++i){
    		ll u = read(),v = read();
    		std::memset(ans,0,sizeof(ans));
    		lca(u,v);
    		ll sum = 0;
    		for(int i = 61;i >= 0;--i){
    			if(ans[i])
    			sum = std::max(sum,sum ^ (ans[i]));
    		}
    		std::cout<<sum<<std::endl;
    	}
    } 
    
  • 相关阅读:
    thinkphp使用ajax程序报500错误
    非隐藏转发和隐藏转发的区别及选择
    表单文件(图片)上传到服务器,权限自动变成363,无法访问
    我收到了互联网应急中心的通报!记sqlmap的正确打开方式。
    css字体可以小于12px!被小米官网打脸
    阿里云CDN添加域名80端口和443端口什么区别?
    网站使用海外服务器,国内访问很慢的解决方案
    linux下设置php文件不区分大小写
    国际化
    Spring boot2.0学习笔记(一)
  • 原文地址:https://www.cnblogs.com/dixiao/p/14546278.html
Copyright © 2020-2023  润新知