社区讨论

玄学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 条回复,欢迎继续交流。

正在加载回复...