WA的一声哭了,救救孩子

P3379 【模板】最近公共祖先(LCA)

你的f[k][0]=k是什么操作???
by 913887524gsd @ 2018-11-09 07:07:49


@[913887524gsd](/space/show?uid=89367) 额,代码好像发错了,这是改到一半的代码,抱歉。 ```cpp #include<cstdio> using namespace std; int n,m,s,fa[500007][27],d[500007],lg[500007],p[1000007],v[1000007],h[500007],l,x,y,z; int f(int k,int w) { for (int i=h[k];i;i=p[i]) { int u=v[i]; if (!d[u]) { d[u]=w+1; fa[u][0]=k; for (int j=1;j<w;++j) fa[u][j]=fa[fa[u][j-1]][j-1]; f(u,w+1); } } } int f1(int vx,int vy) { if (d[vx]<d[vy]) { int num=vx; vx=vy; vy=num; } for (int i=lg[vx];i>=0;--i) if(d[fa[vx][i]]>=d[vy]) vx=fa[vx][i]; if (vx==vy) return vx; for (int i=lg[vx];i>=0;--i) if (fa[vx][i]!=fa[vy][i]) { vx=fa[vx][i]; vy=fa[vy][i]; } return fa[vx][0]; } int main() { scanf("%d%d%d",&n,&m,&s); for (int i=2;i<=n;++i) lg[i]=lg[i>>1]+1; for (int i=1;i<n;++i) { scanf("%d%d",&x,&y); v[++l]=x; p[l]=h[y]; h[y]=l; v[++l]=y; p[l]=h[x]; h[x]=l; } d[s]=1; f(s,1); for (int i=1;i<=m;++i) { scanf("%d%d",&x,&y); printf("%d\n",f1(x,y)); } return 0; } ```
by 奔跑吧柯哀 @ 2018-11-09 07:09:53


f[k][0]=k; 23333
by 用户已注销 @ 2018-11-09 07:10:25


@[913887524gsd](/space/show?uid=89367) 20分代码 ```cpp #include<cstdio> using namespace std; int n,m,s,fa[500007][27],d[500007],lg[500007],p[1000007],v[1000007],h[500007],l,x,y,z; int f(int k,int w) { for (int i=h[k];i;i=p[i]) { int u=v[i]; if (!d[u]) { d[u]=w+1; fa[u][0]=k; for (int j=1;j<w;++j) fa[u][j]=fa[fa[u][j-1]][j-1]; f(u,w+1); } } } int f1(int vx,int vy) { if (d[vx]<d[vy]) { int num=vx; vx=vy; vy=num; } for (int i=lg[vx];i>=0;--i) if(d[fa[vx][i]]>=d[vy]) vx=fa[vx][i]; if (vx==vy) return vx; for (int i=lg[vx];i>=0;--i) if (fa[vx][i]!=fa[vy][i]) { vx=fa[vx][i]; vy=fa[vy][i]; } return fa[vx][0]; } int main() { scanf("%d%d%d",&n,&m,&s); for (int i=2;i<=n;++i) lg[i]=lg[i>>1]+1; for (int i=1;i<n;++i) { scanf("%d%d",&x,&y); v[++l]=x; p[l]=h[y]; h[y]=l; v[++l]=y; p[l]=h[x]; h[x]=l; } d[s]=1; f(s,1); for (int i=1;i<=m;++i) { scanf("%d%d",&x,&y); printf("%d\n",f1(x,y)); } return 0; } ```
by 奔跑吧柯哀 @ 2018-11-09 07:11:12


@[fzszkl](/space/show?uid=23323) 抱歉,发错了,那是改到一半的代码。
by 奔跑吧柯哀 @ 2018-11-09 07:11:44


你的求lca那里有问题,应该为``` for(int i=lg[d[dx]];i>=0;i--) ```
by 913887524gsd @ 2018-11-09 07:21:24


找到一个小错。。。 ``` for (int i=lg[vx];i>=0;--i) if(d[fa[vx][i]]>=d[vy]) vx=fa[vx][i]; if (vx==vy) return vx; for (int i=lg[vx];i>=0;--i) if (fa[vx][i]!=fa[vy][i]) { vx=fa[vx][i]; vy=fa[vy][i]; } ``` lg[vx]...把编号log一下好像没啥意义吧 我不会写倍增LCA啊丢人了,建议学树链剖分LCA,代码短跑的还快
by 用户已注销 @ 2018-11-09 07:21:52


嗯。。。我试着交了一下你的代码,AC了。 ``` #include<cstdio> using namespace std; int n,m,s,fa[500007][27],d[500007],lg[500007],p[1000007],v[1000007],h[500007],l,x,y,z; int f(int k,int w) { for (int i=h[k];i;i=p[i]) { int u=v[i]; if (!d[u]) { d[u]=w+1; fa[u][0]=k; for (int j=1;j<=lg[w];++j) fa[u][j]=fa[fa[u][j-1]][j-1]; f(u,w+1); } } } int f1(int vx,int vy) {//printf("a\n"); if (d[vx]<d[vy]) { int num=vx; vx=vy; vy=num; }//printf("b\n"); for (int i=lg[d[vx]]+1;i>=0;--i) if(d[fa[vx][i]]>=d[vy]) vx=fa[vx][i]; if (vx==vy) return vx;//printf("c\n"); for (int i=lg[d[vx]]+1;i>=0;--i) if (fa[vx][i]!=fa[vy][i]) { vx=fa[vx][i]; vy=fa[vy][i]; }//printf("d\n"); return fa[vx][0]; } int main() { scanf("%d%d%d",&n,&m,&s); for (int i=2;i<=n;++i) lg[i]=lg[i>>1]+1; for (int i=1;i<n;++i) { scanf("%d%d",&x,&y); v[++l]=x; p[l]=h[y]; h[y]=l; v[++l]=y; p[l]=h[x]; h[x]=l; } d[s]=1; f(s,1); for (int i=1;i<=m;++i) { scanf("%d%d",&x,&y); printf("%d\n",f1(x,y)); } return 0; } ``` 一番魔改,希望你不要介意 其实就是倍增的时候改成了log+1就A了。。。
by 用户已注销 @ 2018-11-09 07:27:30


树剖 评测状态 Accepted 100 用时: 659ms / 内存: 21524KB
by 用户已注销 @ 2018-11-09 07:32:44


@[fzszkl](/space/show?uid=23323) 恩,我改成lg+1了,多了十分 [评测记录](https://www.luogu.org/record/show?rid=13521726) ```cpp #include<cstdio> using namespace std; int n,m,s,fa[500007][27],d[500007],lg[500007],p[1000007],v[1000007],h[500007],l,x,y,z; int f(int k,int w) { for (int i=h[k];i;i=p[i]) { int u=v[i]; if (!d[u]) { d[u]=w+1; fa[u][0]=k; for (int j=1;j<w;++j) fa[u][j]=fa[fa[u][j-1]][j-1]; f(u,w+1); } } return 0; } int f1(int vx,int vy) { if (d[vx]<d[vy]) { int num=vx; vx=vy; vy=num; } for (int i=lg[d[vx]]+1;i>=0;--i) if(d[fa[vx][i]]>=d[vy]) vx=fa[vx][i]; if (vx==vy) return vx; for (int i=lg[d[vx]]+1;i>=0;--i) if (fa[vx][i]!=fa[vy][i]) { vx=fa[vx][i]; vy=fa[vy][i]; } return fa[vx][0]; } int main() { scanf("%d%d%d",&n,&m,&s); for (int i=2;i<=n;++i) lg[i]=lg[i>>1]+1; for (int i=1;i<n;++i) { scanf("%d%d",&x,&y); v[++l]=x; p[l]=h[y]; h[y]=l; v[++l]=y; p[l]=h[x]; h[x]=l; } d[s]=1; f(s,1); for (int i=1;i<=m;++i) { scanf("%d%d",&x,&y); printf("%d\n",f1(x,y)); } return 0; } ```
by 奔跑吧柯哀 @ 2018-11-09 07:37:50


| 下一页