"Brush title" lucky number

Positive solution of linear group.

Lca general and as a pre-f [x] [i] is x until x $ 2 ^ i $ walking step and linear group to the root,

Then it may be processed and combined and lca as to obtain a linear base path.

Before proceeding to.

But I do not have control memset, card card for a long time often did before, and finally changed to A at a memset.

Cards often really disgusting.

 

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#define clear(a) memset((a).d,0,sizeof((a).d))
using namespace std;


typedef long long ll;
const int maxn=2e4+5;
ll n,q,x,y;
ll w[maxn];
char xB[(1<<15)+10],*xS=xB,*xT=xB;
#define gtc (xS==xT&&(xT=(xS=xB)+fread(xB,1,1<<15,stdin),xS==xT)?0:*xS++)
inline void read(ll &x){
  register char ch=gtc;
  for(x=0;ch<'0'||ch>'9';ch=gtc);
  for(;ch>='0'&&ch<='9';x=(x<<1)+(x<<3)+ch-'0',ch=gtc);
}
inline void print(ll x)
{
    if(x<0) {putchar('-'); x=-x;}
    if(x>9) print(x/10);
    putchar(x%10+48);
    return;
}
struct Road{
    int tot,t[maxn<<1],nxt[maxn<<1],first[maxn];
    void add(int x,int y)
    {
        t[++tot]=y;
        nxt[tot]=first[x];
        first[x]=tot;
    }
}eage;
struct Least_Common_Ancetor{
    struct line_bsis{
        ll d[63];
        void insert(ll x)
        {
            for(register int i=61;i>=0;i--)
                if((x>>i)&1)
                {
                    if(!d[i]) {d[i]=x;break;}
                    x^=d[i];
                }
        }
        ll ma()
        {
            ll ans=0;
            for(register int i=61;i>=0;i--)
                if((ans^d[i])>ans)
                    ans^=d[i];
            return ans;
        }
    }lb[maxn][30],own[maxn],tmp,r;
    int p,d[maxn],f[maxn][30];
    inline line_bsis merge(const line_bsis &a,const line_bsis &b)
    {
        clear(r);
        for(register int i=60;i>=0;i--)
        {
            if(a.d[i]) r.insert(a.d[i]);
            if(b.d[i]) r.insert(b.d[i]);
        }
        return r;
    }
    inline void lmerge(line_bsis &a,line_bsis &b)
    {
        for(register int i=60;i>=0;--i)
            if(b.d[i])
                a.insert(b.d[i]);
    }
    void init()
    {
        p=log2(n)+1;
        for(int i=1;i<=n;i++) own[i].insert(w[i]);
        dfs(1,0);
    }
    inline void dfs(int x,int fa)
    {
        for(int i=eage.first[x];i;i=eage.nxt[i])
            if(eage.t[i]!=fa)
            {
                int t=eage.t[i];
                d[t]=d[x]+1;
                f[t][0]=x;lb[t][0]=merge(own[x],own[t]);
                for(int j=1;j<=p;j++)
                {
                    f[t][j]=f[f[t][j-1]][j-1];
                    if(f[t][j]==0) break;
                    lb[t][j]=merge(lb[t][j-1],lb[f[t][j-1]][j-1]);
                }
                dfs(t,x);
            }
    }
    inline int LCA(int x,int y)
    {
        clear(tmp);
        if(d[x]<d[y]) swap(x,y);
        int t=d[x]-d[y];
        for(int i=p;t;i--)
            if(t&(1<<i))
            {
                lmerge(tmp,lb[x][i]);
                x=f[x][i];t^=(1<<i);
            }
        if(x==y) return x;
        for(int i=p;i>=0;i--)
            if(f[x][i]^f[y][i])
            {
                lmerge(tmp,lb[x][i]);
                lmerge(tmp,lb[y][i]);
                x=f[x][i];y=f[y][i];
            }
        lmerge(tmp,lb[x][0]);
        lmerge(tmp,lb[y][0]);
        return f[x][0];
    }
}zt;
int main()
{
    read(n);read(q);
    for(int i=1;i<=n;i++) read(w[i]);
    for(int i=1;i<=n-1;i++)
    {
        read(x);read(y);
        eage.add(x,y);eage.add(y,x);
    }
    zt.init();
    /*for(int i=1;i<=n;i++)
        for(int j=0;j<=zt.p;j++)
            cout<<i<<":"<<j<<" "<<zt.lb[i][j].ma()<<endl;*/
    while(q--)
    {
        read(x);read(y);
        if(x==y)
        {
            print(zt.own[x].ma());puts("");
            continue;
        }
        zt.LCA(x,y);
        print(zt.tmp.ma());puts("");
    }
    return 0;
}
Lucky number

 

Guess you like

Origin www.cnblogs.com/Lrefrain/p/11222907.html