BZOJ 4568 [Scoi2016]幸运数字
题解:
倍增维护线性基
线性基合并
注意,少传参,浪费时间
//少传参 #include<iostream> #include<cstdio> #include<cstring> using namespace std; typedef long long Lint; const int maxn=20009; const int u=61; int n,TT; Lint val[maxn]; struct BS{ Lint a[u+2]; BS(){ memset(a,0,sizeof(a)); } void Clea(){ memset(a,0,sizeof(a)); } }g[maxn][15],T;//u=14 int f[maxn][15]={0}; int dep[maxn]={0}; void MerNum(Lint x){ for(int j=u;j>=1;--j){ if(!(x&(1LL<<(j-1))))continue; if(T.a[j]){ x^=T.a[j]; }else{ T.a[j]=x;break; } } } void MerBS(BS B){ for(int j=u;j>=1;--j){ if(B.a[j])MerNum(B.a[j]); } } int cntedge=0; int head[maxn]={0}; int to[maxn<<1],nex[maxn<<1]; void Addedge(int x,int y){ nex[++cntedge]=head[x]; to[cntedge]=y; head[x]=cntedge; } void Dfs(int x,int fa){ f[x][0]=fa; dep[x]=dep[fa]+1; for(int i=head[x];i;i=nex[i]){ if(to[i]==fa)continue; Dfs(to[i],x); } } void LCAinit(){ for(int i=1;i<=n;++i){ T.Clea(); MerNum(val[i]); MerNum(val[f[i][0]]); g[i][0]=T; } for(int j=1;j<=14;++j){ for(int i=1;i<=n;++i){ f[i][j]=f[f[i][j-1]][j-1]; if(f[i][j]){ T.Clea(); MerBS(g[i][j-1]);MerBS(g[f[i][j-1]][j-1]); g[i][j]=T; } } } } Lint Getans(){ Lint ret=0; for(int j=u;j>=1;--j){ if((ret^T.a[j])>ret)ret=(ret^T.a[j]); } return ret; } Lint Querymax(int u,int v){ if(u==v)return val[u]; T.Clea(); if(dep[u]<dep[v])swap(u,v); for(int j=14;j>=0;--j){ if(dep[f[u][j]]>=dep[v]){ MerBS(g[u][j]); u=f[u][j]; } } if(u==v){ return Getans(); } for(int j=14;j>=0;--j){ if(f[u][j]!=f[v][j]){ MerBS(g[u][j]); MerBS(g[v][j]); u=f[u][j];v=f[v][j]; } } MerNum(val[u]); MerNum(val[v]); MerNum(val[f[u][0]]); return Getans(); } int main(){ scanf("%d%d",&n,&TT); for(int i=1;i<=n;++i)scanf("%lld",&val[i]); for(int i=1;i<=n-1;++i){ int x,y;scanf("%d%d",&x,&y); Addedge(x,y); Addedge(y,x); } Dfs(1,0); LCAinit(); while(TT--){ int x,y; scanf("%d%d",&x,&y); printf("%lld\n",Querymax(x,y)); } return 0; }
致歉:笔者已经意识到这是一篇几乎没有价值的文章,给您的阅读带来不好的体验,并且干扰了您的搜索环境,非常抱歉!