zoukankan      html  css  js  c++  java
  • CF208E Blood Cousins(树上启发式合并)

    转化题目,题目要求的是K级祖先,我们可以对于每个询问先跳到祖先,那么就是求对于这个祖先,depth[u]+k的个数是多少个,然后-1就是答案

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> pll;
    const int N=2e5+10;
    int rt,f[N][25];
    int depth[N],sz[N],son[N];
    vector<pll> num[N];
    int h[N],ne[N],e[N],idx;
    int res[N];
    int ans[N];
    void add(int a,int b){
        e[idx]=b,ne[idx]=h[a],h[a]=idx++;
    }
    void dfs1(int u,int fa){
        depth[u]=depth[fa]+1;
        f[u][0]=fa;
        int i;
        for(i=1;i<=21;i++){
            f[u][i]=f[f[u][i-1]][i-1];
        }
        sz[u]=1;
        for(i=h[u];i!=-1;i=ne[i]){
            int j=e[i];
            if(j==fa)
                continue;
            dfs1(j,u);
            sz[u]+=sz[j];
            if(sz[j]>sz[son[u]]){
                son[u]=j;
            }
        }
    }
    int flag;
    void cal(int u,int fa,int x){
        res[depth[u]]+=x;
        int i,j;
        for(i=h[u];i!=-1;i=ne[i]){
            int j=e[i];
            if(j==fa||j==flag)
                continue;
            cal(j,u,x);
        }
    }
    void dfs(int u,int fa,int keep){
        int i;
        for(i=h[u];i!=-1;i=ne[i]){
            int j=e[i];
            if(j==fa||j==son[u])
                continue;
            dfs(j,u,0);
        }
        if(son[u]){
            dfs(son[u],u,1);
            flag=son[u];
        }
        cal(u,fa,1);
        flag=0;
        for(i=0;i<num[u].size();i++){
            auto x=num[u][i];
            ans[x.first]=res[x.second]-1;
            //cout<<x.first<<" hhjjj "<<res[x.second]<<" "<<x.second<<endl;
        }
        //res[depth[u]]++;
        if(!keep){
            cal(u,fa,-1);
        }
    }
    int vis[N];
    int main(){
        ios::sync_with_stdio(false);
        int i,j;
        int n,m;
        memset(h,-1,sizeof h);
        cin>>n;
        for(i=1;i<=n;i++){
            int x;
            cin>>x;
            if(x!=0){
                vis[i]=1;
                add(x,i);
            }
        }
        for(i=1;i<=n;i++){
            if(!vis[i])
                dfs1(i,0);
        }
        cin>>m;
        for(j=1;j<=m;j++){
            int x,y;
            cin>>x>>y;
            int flag=0;
            int tmp=y;
            for(int i=20;i>=0;i--){
                if(f[x][i]&&y>=(1<<i)){
                    y-=(1<<i);
                    x=f[x][i];
                }
            }
            if(y){
                ans[i]=0;
                continue;
            }
            //cout<<x<<" gg "<<depth[x]+tmp<<endl;
            num[x].push_back({j,depth[x]+tmp});
        }
        for(i=1;i<=n;i++){
            if(!vis[i]){
                dfs(i,0,0);
                //flag=0;
            }
        }
        for(i=1;i<=m;i++){
            cout<<ans[i]<<" ";
        }
        cout<<endl;
        return 0;
    }
    View Code
    没有人不辛苦,只有人不喊疼
  • 相关阅读:
    PHP使用Redis的GEO地理信息类型
    Redis长短链接的区别
    Linux之ln文件创建链接
    xml与json格式互转
    爬虫实例:唐诗宋词爬虫
    爬虫实例:天猫商品评论爬虫
    爬虫实例:饿了么爬虫
    爬虫实例:中国日报高频词汇爬虫
    爬虫实例:今日头条爬虫
    特殊类型的列表切片
  • 原文地址:https://www.cnblogs.com/ctyakwf/p/14695837.html
Copyright © 2011-2022 走看看