zoukankan      html  css  js  c++  java
  • BZOJ 4568 [Scoi2016]幸运数字 ——线性基 倍增

    【题目分析】

        考虑异或的最大值,维护线性基就可以了。

        但是有多次的询问,树剖或者倍增都可以。

        想了想树剖动辄数百行的代码。

        算了,我还是写倍增吧。

        注:被位运算和大于号的优先级坑了一次,QaQ

    【代码】

    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <cmath>
    
    #include <set>
    #include <map>
    #include <string>
    #include <algorithm>
    #include <vector>
    #include <iostream>
    #include <queue>
    
    using namespace std;
    
    #define ll long long 
    #define F(i,j,k) for (int i=j;i<=k;++i)
    #define D(i,j,k) for (int i=j;i>=k;--i)
    #define maxn 20005
    #define mlog 20
    #define mxle 64
    #define mxed 50005
    
    int Getint()
    {
        int x=0,f=1; char ch=getchar();
        while (ch<'0'||ch>'9') {if (ch=='-') f=-1; ch=getchar();}
        while (ch>='0'&&ch<='9') {x=x*10+ch-'0'; ch=getchar();}
        return x*f;
    }
    
    ll Getll()
    {
        ll x=0,f=1; char ch=getchar();
        while (ch<'0'||ch>'9') {if (ch=='-') f=-1; ch=getchar();}
        while (ch>='0'&&ch<='9') {x=x*10+ch-'0'; ch=getchar();}
        return x*f;
    }
    
    void Finout()
    {
        #ifndef ONLINE_JUDGE
        freopen("in.txt","r",stdin);
        #endif
    }
    
    struct Base{
    	ll lb[mxle];
    	void add(ll x)
    	{
    		D(i,63,0)
    		{
    			if ((x>>i)&1)
    			{
    				if (!lb[i]) {lb[i]=x;break;}
    				else x^=lb[i];
    			}
    		}
    	}
    	void init(ll x){memset(lb,0,sizeof lb);add(x);}
    };
    
    Base add(Base x,Base y)
    {
    	Base ret=x;
    	F(i,0,63) if (y.lb[i]) ret.add(y.lb[i]);
    	return ret;
    }
    
    int f[maxn][mlog],n,q,h[mxed],to[mxed],ne[mxed],en=0,dst[maxn];
    Base g[maxn][mlog];
    
    void add(int a,int b)
    {
    	to[en]=b; ne[en]=h[a]; h[a]=en++;
    	to[en]=a; ne[en]=h[b]; h[b]=en++;
    }
    
    void dfs(int o)
    {
    	for (int i=h[o];i>=0;i=ne[i])
    		if (f[o][0]!=to[i])
    		{
    			f[to[i]][0]=o;
    			dst[to[i]]=dst[o]+1;
    			dfs(to[i]);
    		}
    }
    
    ll query(Base x)
    {
    	ll sum=0;
    	D(i,63,0)
    	if ((x.lb[i]^sum)>sum) sum^=x.lb[i];
    	return sum;
    }
    
    ll ask(int a,int b)
    {
    	if (dst[a]<dst[b]) swap(a,b);
    	Base ret;ret.init(0);
    	int dist=dst[a]-dst[b];
    	D(i,mlog-1,0)
    		if ((dist>>i)&1)
    		{
    			ret=add(ret,g[a][i]);
    			a=f[a][i];
    		}
    	if (a==b)
    	{
    		ret=add(ret,g[a][0]);
    		return query(ret);
    	}
    	D(i,mlog-1,0)
    		if (f[a][i]!=f[b][i])
    		{
    			ret=add(ret,g[a][i]);
    			ret=add(ret,g[b][i]);
    			a=f[a][i];b=f[b][i];
    		}
    	ret=add(ret,g[a][1]);
    	ret=add(ret,g[b][0]);
    	return query(ret);
    }
    
    int main()
    {
    	Finout();
    	memset(h,-1,sizeof h);
    	n=Getint(); q=Getint();
    	F(i,1,n) g[i][0].init(Getll());
    	F(i,1,n-1) add(Getint(),Getint());
    	dfs(1);
    	F(i,1,mlog-1)
    		F(j,1,n)
    		{	
    			f[j][i]=f[f[j][i-1]][i-1];
    			g[j][i]=add(g[j][i-1],g[f[j][i-1]][i-1]);
    		}
    	F(i,1,q) printf("%lld
    ",ask(Getint(),Getint()));
    }
    

      

  • 相关阅读:
    document.getElementById的简便方式
    uri编解码
    javascript数组
    前端网站收藏
    html5 canvas
    interview material
    Merge into(oracle)
    机器学习入门二 ----- 机器学习术语表
    机器学习入门一 ------- 什么是机器学习,机器学习的在实际中的用处
    Dubbo 源码分析系列之一环境搭建
  • 原文地址:https://www.cnblogs.com/SfailSth/p/6352095.html
Copyright © 2011-2022 走看看