P3292 [SCOI2016]幸运数字

Posted nofind

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P3292 [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;
}

以上是关于P3292 [SCOI2016]幸运数字的主要内容,如果未能解决你的问题,请参考以下文章

Luogu P3292 [SCOI2016]幸运数字

SCOI2016 幸运数字

LibreOJ #2013. 「SCOI2016」幸运数字

bzoj 4568: [Scoi2016]幸运数字

BZOJ4568: [Scoi2016]幸运数字

[SCOI2016]幸运数字