BZOJ 4568 倍增维护线性基
2017-01-22 23:14
176 查看
在树的路径上选取一些点 使得这些点权xor后的结果最大
思路:
![](http://img.blog.csdn.net/20170122231147374?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXFfMzE3ODU4NzE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
时限60s 59696ms卡过去了哈哈哈
思路:
时限60s 59696ms卡过去了哈哈哈
//By SiriusRen #include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef long long ll; const int N=20005; ll Temp[128],ans; int n,q,first ,next ,v ,tot,xx,yy,deep ; void add(int x,int y){v[tot]=y,next[tot]=first[x],first[x]=tot++;} struct Node{int anc,num;ll eli[62];}fa [16],G ,jy; int Gauss(Node a,Node b){ int num=a.num+b.num,flag=1; for(int i=1;i<=a.num;i++)Temp[i]=a.eli[i]; for(int i=1;i<=b.num;i++)Temp[i+a.num]=b.eli[i]; for(int i=60,j;~i;i--){ for(j=flag;j<=num;j++)if(Temp[j]&(1ll<<i))break; if(j==num+1)continue; swap(Temp[flag],Temp[j]); for(int k=1;k<=num;k++)if(k!=flag&&Temp[k]&(1ll<<i))Temp[k]^=Temp[flag]; flag++; } return flag-1; } void dfs(int x){ for(int i=1;i<=15;i++){ fa[x][i].anc=fa[fa[x][i-1].anc][i-1].anc; fa[x][i].num=Gauss(fa[x][i-1],fa[fa[x][i-1].anc][i-1]); for(int j=1;j<=fa[x][i].num;j++)fa[x][i].eli[j]=Temp[j]; } for(int i=first[x];~i;i=next[i]){ if(v[i]!=fa[x][0].anc){ fa[v[i]][0].anc=x,deep[v[i]]=deep[x]+1; fa[v[i]][0].num=Gauss(G[v[i]],G[x]); for(int j=1;j<=fa[v[i]][0].num;j++)fa[v[i]][0].eli[j]=Temp[j]; dfs(v[i]); } } } void LCA(int x,int y){ if(deep[x]<deep[y])swap(x,y); for(int i=15;~i;i--)if(deep[x]-(1<<i)>=deep[y]){ jy.num=Gauss(jy,fa[x][i]); for(int j=1;j<=jy.num;j++)jy.eli[j]=Temp[j]; x=fa[x][i].anc; } if(x==y){jy.num=Gauss(jy,G[x]);for(int j=1;j<=jy.num;j++)jy.eli[j]=Temp[j];return;} for(int i=15;~i;i--){ if(fa[x][i].anc!=fa[y][i].anc){ jy.num=Gauss(jy,fa[x][i]); for(int j=1;j<=jy.num;j++)jy.eli[j]=Temp[j]; jy.num=Gauss(jy,fa[y][i]); for(int j=1;j<=jy.num;j++)jy.eli[j]=Temp[j]; x=fa[x][i].anc,y=fa[y][i].anc; } } jy.num=Gauss(jy,fa[x][0]); for(int j=1;j<=jy.num;j++)jy.eli[j]=Temp[j]; jy.num=Gauss(jy,fa[y][0]); for(int j=1;j<=jy.num;j++)jy.eli[j]=Temp[j]; } int main(){ memset(first,-1,sizeof(first)); scanf("%d%d",&n,&q); for(int i=1;i<=n;i++)scanf("%lld",&G[i].eli[1]),G[i].num=1; for(int i=1;i<n;i++)scanf("%d%d",&xx,&yy),add(min(xx,yy),max(xx,yy)); deep[1]=1,dfs(1); for(int i=1;i<=q;i++){ scanf("%d%d",&xx,&yy); jy.num=ans=0,LCA(xx,yy); for(int i=1;i<=jy.num;i++)ans^=jy.eli[i]; printf("%lld\n",ans); } }
相关文章推荐
- BZOJ 4568 倍增维护线性基
- bzoj 4568: [Scoi2016]幸运数字 倍增维护线性基
- BZOJ 4568 [Scoi2016]幸运数字 【倍增线性基
- BZOJ 4568 幸运数字(在线倍增法+线性基)
- [BZOJ]4568: [Scoi2016]幸运数字 倍增+线性基
- bzoj 4568: [Scoi2016]幸运数字(树上倍增+线性基)
- bzoj 4568 [Scoi2016]幸运数字 倍增+线性基
- BZOJ 4568: [Scoi2016]幸运数字 [线性基 倍增]
- BZOJ 4568 [Scoi2016]幸运数字 ——线性基 倍增
- bzoj 4568: [Scoi2016]幸运数字【树链剖分+线段树+线性基】
- 【BZOJ-4568】幸运数字 树链剖分 + 线性基合并
- BZOJ4568: [Scoi2016]幸运数字【线性基】
- 4568: [Scoi2016]幸运数字 倍增+线性基
- bzoj 4568: [Scoi2016]幸运数字 (高斯消元求解线性基)
- 学习线性基 bzoj 4568 幸运数字
- BZOJ4568 SCOI2016 幸运数字 倍增的思想维护线性基(线性基详解)
- [BZOJ]4568 [SCOI2016] 幸运数字 线性基合并
- BZOJ 2819: Nim dfs序维护树状数组,倍增
- 【bzoj1977】【严格次小生成树】倍增维护链上最大次大值
- BZOJ_4184_shallot_线段树按时间分治维护线性基