当前位置 : 主页 > 手机开发 > harmonyos >

CF 208E

来源:互联网 收集:自由互联 发布时间:2023-10-08
倍增求LCA模板 #includecstdio#includecstring#includevector#includealgorithm#define N 100100using namespace std;vectorintvec,vec1[N];int head[N],cnt;struct Edge{ int v,next;}edge[N];int tim,fa[N],b[N],son[N],dep[N],p[N][18];int ans[N];vo


倍增求LCA模板

#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
#define N 100100
using namespace std;
vector<int>vec,vec1[N];
int head[N],cnt;
struct Edge{
    int v,next;
}edge[N];
int tim,fa[N],b[N],son[N],dep[N],p[N][18];
int ans[N];
void init(){
    vec.clear();
    memset(head,-1,sizeof(head));
    memset(dep,0,sizeof(dep));
    memset(p,0,sizeof(p));
    memset(son,0,sizeof(son));
    cnt=tim=0;
}
void addedge(int u,int v){
    edge[cnt].v=v;
    edge[cnt].next=head[u];
    head[u]=cnt++;
}
void dfs(int u){
    int i;
    b[u]=++tim;
    dep[u]=dep[fa[u]]+1;
    vec1[dep[u]].push_back(tim);
    p[u][0]=fa[u];
    for(i=1;i<18;i++)p[u][i]=p[p[u][i-1]][i-1];
    son[u]=1;
    for(i=head[u];i!=-1;i=edge[i].next){
        int v=edge[i].v;
        dfs(v);
        son[u]+=son[v];
    }
}
int find(int u,int num){    //返回u的第num代祖先
    for(int i=0;i<18;i++)
        if((1<<i)&num)
            u=p[u][i];
    return u;
}
int solve(int t,int num){   //二分查找区间[0,vec1[num].size()-1]内vec1[num][i]<=t中最大的i
    int h=vec1[num].size()-1,l=0,sum=-1;
    while(l<=h){
        int mid=(h+l)>>1;
        if(vec1[num][mid]>t)
            h=mid-1;
        else{
            sum=mid;
            l=mid+1;
        }
    }
    return sum;
}
int main(){
    int i,v,n,m,num;
    init();
    scanf("%d",&n);
    for(i=1;i<=n;i++){
        scanf("%d",&v);
        fa[i]=v;
        if(v==0)vec.push_back(i);
        addedge(v,i);
    }
    for(i=0;i<vec.size();i++)
        dfs(vec[i]);
    scanf("%d",&m);
    for(i=1;i<=m;i++){
        scanf("%d %d",&v,&num);
        int u=find(v,num);
        if(!u)ans[i]=0;
        else ans[i]=solve(b[u]+son[u]-1,dep[v])-solve(b[u]-1,dep[v])-1;
    }
    for(i=1;i<=m;i++)
        if(i==1)printf("%d",ans[i]);
        else printf(" %d",ans[i]);
    printf("\n");
	return 0;
}









上一篇:HDU 4005
下一篇:没有了
网友评论