社区讨论
玄学MLE&RE求调
AT_abc267_f [ABC267F] Exactly K Steps参与者 3已保存回复 8
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 8 条
- 当前快照
- 1 份
- 快照标识符
- @lo1248qq
- 此快照首次捕获于
- 2023/10/22 13:57 2 年前
- 此快照最后确认于
- 2023/11/02 13:26 2 年前
rt
我的做法是先求一条直径,then以直径两端点为树根跑树剖,最后用树剖来跳k级祖先
CPP#include<bits/stdc++.h>
#define N 2
#define M 200005
using namespace std;
int n,cnt,fir[M],fa[N][M],dep[N][M],p1,p2,son[N][M],t[N][M],pos[N],sz[N][M],fp[N][M],p[N][M];
int k_fa(int,int,int);
struct E{ int nex,to;}e[N<<1];
void dfs(int,int,int),dfs2(int,int,int),add(int,int);
signed main(){
// freopen("intoxicated.in","r",stdin);
// freopen("intoxicated.out","w",stdout);
scanf("%d",&n);
for(int i=1,a,b;i<n;++i)
scanf("%d%d",&a,&b),add(a,b);
dfs(1,1,0),dfs(p1,p1,1);
for(int i=1;i<=n;++i) fa[0][i]=0,dep[0][i]=0,son[0][i]=0,sz[0][i]=0;
dfs(p2,p2,0); dfs2(p1,p1,1),dfs2(p2,p2,0);
int m;
scanf("%d",&m);
while(m--){
int u,d; scanf("%d%d",&u,&d);
printf("%d\n",d<=max(dep[0][u],dep[1][u])?k_fa(u,d,dep[0][u]>dep[1][u]?0:1):-1);
}
return 0;
}
void dfs(int no,int faa,int flg){
fa[flg][no]=faa,++sz[flg][no];
for(int i=fir[no];i;i=e[i].nex){
int v=e[i].to;
if(v==faa) continue;
dep[flg][v]=dep[flg][no]+1;
if(flg&&dep[flg][v]>dep[flg][p2]) p2=v;
else if(!p2&&!flg&&dep[flg][v]>dep[flg][p1]) p1=v;
dfs(v,no,flg);
sz[flg][no]+=sz[flg][v];
if(sz[flg][son[flg][no]]<sz[flg][v]) son[flg][no]=v;
}
}
void dfs2(int no,int to,int flg){
p[flg][no]=++pos[flg],fp[flg][pos[flg]]=no,t[flg][no]=to;
if(!son[flg][no]) return ;
dfs2(son[flg][no],to,flg);
for(int i=fir[no];i;i=e[i].nex){
int v=e[i].to;
if(v!=fa[flg][no]&&v!=son[flg][no])
dfs2(v,v,flg);
}
}
int k_fa(int no,int dep,int flg){
while(dep>p[flg][no]-p[flg][t[flg][no]])
dep-=(p[flg][no]-p[flg][t[flg][no]]+1),no=fa[flg][t[flg][no]];
return fp[flg][p[flg][no]-dep];
}
void add(int a,int b){
e[++cnt].nex=fir[a],e[cnt].to=b,fir[a]=cnt;
e[++cnt].nex=fir[b],e[cnt].to=a,fir[b]=cnt;
}
回复
共 8 条回复,欢迎继续交流。
正在加载回复...