E. Blood Cousins(dsu+倍增)

题:https://codeforces.com/problemset/problem/208/E

题意:给定树,问m个询问,每个询问vi,pi,要查询和vi有pi级相同祖先的对数;

分析:支持离线且没修改,考虑dsu,,因为树每个节点向上的路径是一定的,所以我们吧询问点vi转移到pi级祖先上,然后问题就变为我们熟悉的找子树中相同高度的个数

#include<bits/stdc++.h>
#include<tr1/unordered_map>
using namespace std;
typedef long long ll;
#define pb push_back
const int M=1e5+5;
struct node{
    int p,id;
};
vector<node>q[M];
vector<int>g[M];
int n,grand[M][20],sz[M],deep[M],cnt[M],root,s,ans[M],son[M],vis[M];
void dfs1(int u){
    sz[u]=1;
    for(int i=1;i<=s;i++){
        grand[u][i]=grand[grand[u][i-1]][i-1];
        if(!grand[u][i])
            break;
    }
    for(auto v:g[u]){
        if(v!=grand[u][0]){
            grand[v][0]=u;
            deep[v]=deep[u]+1;
            dfs1(v);
            sz[u]+=sz[v];
            if(sz[son[u]]<sz[v])
                son[u]=v;
        }
    }
}
void init(){
    s=floor(log(1.0*n)/log(2.0));
    deep[0]=0;
    dfs1(root);
}
void update(int u,int fa,int k){
    cnt[deep[u]]+=k;
    for(auto v:g[u])
        if(v!=fa&&!vis[v])
            update(v,u,k);
}
void dfs2(int u,int fa,int sign){
    for(auto v:g[u]){
        if(v!=fa&&v!=son[u])
            dfs2(v,u,0);
    }
    if(son[u])
        dfs2(son[u],u,1),vis[son[u]]=1;
    update(u,fa,1);
    for(auto i:q[u]){
        int id=i.id;
        int p=i.p;
        ans[id]=cnt[p+deep[u]]-1;
    }
    if(son[u])
        vis[son[u]]=0;
    if(!sign)
        update(u,fa,-1);
}
int main(){
    scanf("%d",&n);
    for(int x,i=1;i<=n;i++){
        scanf("%d",&x);
        g[i].pb(x);
        g[x].pb(i);
    }
    init();
    int m;
    scanf("%d",&m);
    for(int i=1;i<=m;i++){
        int x,y,z;
        scanf("%d%d",&x,&y);
        z=y;
        for(int j=18;j>=0;j--){
            int tmp=1<<j;
            while(y-tmp>=0&&grand[x][j]!=0){
                x=grand[x][j];
                y-=tmp;
            }
        }
        if(y==0)
            q[x].pb(node{z,i});
    }
    dfs2(0,-1,0);
    for(int i=1;i<=m;i++)
        printf("%d ",ans[i]);
    return 0;
}
View Code

猜你喜欢

转载自www.cnblogs.com/starve/p/12657111.html