zoukankan      html  css  js  c++  java
  • luoguP3292 [SCOI2016]幸运数字(倍增做法)

    题意

    线性基套上树上倍增即可,注意边界。

    code:

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int maxn=20010;
    int n,m,cnt,t;
    int head[maxn],dep[maxn];
    int f[maxn][20];
    ll a[maxn];
    struct edge{int to,nxt;}e[maxn<<1];
    struct Xord
    {
    	ll d[65];
    	Xord(){memset(d,0,sizeof(d));}
    	inline void insert(ll x)
    	{
    		for(int i=60;~i;i--)
    		{
    			if(!(x&(1ll<<i)))continue;
    			if(!d[i]){d[i]=x;return;}
    			else x^=d[i];
    		}
    	}
    	inline ll query()
    	{
    		ll res=0;
    		for(int i=60;~i;i--)res=max(res,res^d[i]);
    		return res;
    	}
    }xord[maxn][20];
    inline void add(int u,int v)
    {
    	e[++cnt].nxt=head[u];
    	head[u]=cnt;
    	e[cnt].to=v;
    }
    void dfs(int x,int fa)
    {
    	dep[x]=dep[fa]+1;
    	for(int i=1;i<=t;i++)
    	{
    		f[x][i]=f[f[x][i-1]][i-1];
    		for(int j=0;j<=60;j++)xord[x][i].d[j]=xord[x][i-1].d[j];
    		for(int j=0;j<=60;j++)if(xord[f[x][i-1]][i-1].d[j])xord[x][i].insert(xord[f[x][i-1]][i-1].d[j]);
    	}
    	for(int i=head[x];i;i=e[i].nxt)
    	{
    		int y=e[i].to;
    		if(y==fa)continue;
    		f[y][0]=x;dfs(y,x);
    	}
    }
    inline ll query(int x,int y)
    {
    	Xord res;
    	if(dep[x]>dep[y])swap(x,y);
    	for(int i=t;~i;i--)
    		if(dep[f[y][i]]>=dep[x])
    		{
    			for(int j=0;j<=60;j++)if(xord[y][i].d[j])res.insert(xord[y][i].d[j]);
    			y=f[y][i];
    		}
    	if(x==y)
    	{
    		res.insert(a[x]);
    		return res.query();
    	}
    	for(int i=t;~i;i--)
    		if(f[x][i]!=f[y][i])
    		{
    			for(int j=0;j<=60;j++)if(xord[x][i].d[j])res.insert(xord[x][i].d[j]);
    			for(int j=0;j<=60;j++)if(xord[y][i].d[j])res.insert(xord[y][i].d[j]);
    			x=f[x][i],y=f[y][i];
    		}
    	res.insert(a[x]),res.insert(a[y]),res.insert(a[f[x][0]]);
    	return res.query();
    }
    int main()
    {
    	//freopen("test.in","r",stdin);
    	//freopen("test.out","w",stdout);
    	scanf("%d%d",&n,&m);t=(int)log2(n)+1;
    	for(int i=1;i<=n;i++)scanf("%lld",&a[i]),xord[i][0].insert(a[i]);
    	for(int i=1;i<n;i++)
    	{
    		int u,v;scanf("%d%d",&u,&v);
    		add(u,v),add(v,u);
    	}
    	dfs(1,0);
    	for(int i=1;i<=m;i++)
    	{
    		int x,y;scanf("%d%d",&x,&y);
    		printf("%lld
    ",query(x,y));
    	}
    	return 0;
    }
    
  • 相关阅读:
    第二周学习总结
    调查问卷
    第五周学习总结
    基于DevExpress的项目窗体统一换肤
    一个Linq to Sql 的关联小问题,搞死人
    VC中类型转换(转载)
    保证一个程序只运行一次
    给所有的Control添加发送键盘事件Tab事件,实现回车键自动跳转到下一个控件[基于Shark Xu]
    遍历进程
    CSS Friendly ASP.NET 2.0 Control Adapters (Beta 2.0)在处理URL时的一个Bug
  • 原文地址:https://www.cnblogs.com/nofind/p/12031143.html
Copyright © 2011-2022 走看看