zoukankan      html  css  js  c++  java
  • CodeForces 740D Alyona and a tree

    倍增,延迟标记。

    考虑一个$u$给他的哪几个祖先$v$贡献了$1$。越往上$dis(v,u)$越大,找到最远的一个还满足条件的$v$,$v$到$u$的父亲这条链上的答案都$+1$。延迟标记一下,然后从叶子节点往上走一遍求前缀和即可。

    #pragma comment(linker, "/STACK:1024000000,1024000000")
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<vector>
    #include<map>
    #include<set>
    #include<queue>
    #include<stack>
    #include<ctime>
    #include<iostream>
    using namespace std;
    typedef long long LL;
    const double pi=acos(-1.0);
    void File()
    {
        freopen("D:\in.txt","r",stdin);
        freopen("D:\out.txt","w",stdout);
    }
    template <class T>
    inline void read(T &x)
    {
        char c = getchar();
        x = 0;
        while(!isdigit(c)) c = getchar();
        while(isdigit(c))
        {
            x = x * 10 + c - '0';
            c = getchar();
        }
    }
    
    int n;
    long long a[200010];
    int to[200010][35];
    long long len[200010][35];
    struct Edge
    {
        int v;
        long long w;
    }e[200010];
    vector<int>G[200010];
    
    int ans[200010];
    
    int get(int x)
    {
        long long L=0;
        int res=x,y=x;
        while(1)
        {
            int flag=0;
            for(int j=30;j>=0;j--)
            {
                if(len[res][j]==-1) continue;
                if(len[res][j]+L>a[y]) continue;
                flag=1; L=len[res][j]+L; res=to[res][j]; break;
            }
            if(flag==0) break;
        }
        return res;
    }
    
    void dfs(int x,int fa,int idx,int dep)
    {
        to[x][0]=fa;
        if(idx!=-1) len[x][0]=e[idx].w;
        else len[x][0]=-1;
    
        for(int j=1;j<=30;j++)
        {
            if((1<<j)>dep)
            {
                to[x][j]=-1; len[x][j]=-1;
                continue;
            }
    
            to[x][j]=to[to[x][j-1]][j-1];
            len[x][j]=len[x][j-1]+len[to[x][j-1]][j-1];
        }
    
        int y=get(x);
        if(y!=x)
        {
            if(to[x][0]!=-1) ans[to[x][0]]++;
            if(to[y][0]!=-1) ans[to[y][0]]--;
        }
    
        for(int i=0;i<G[x].size();i++)
        {
            int id=G[x][i];
            dfs(e[id].v,x,id,dep+1);
        }
    }
    
    void F(int x)
    {
        for(int i=0;i<G[x].size();i++)
        {
            int id=G[x][i];
            F(e[id].v);
            ans[x]+=ans[e[id].v];
        }
    }
    
    int main()
    {
        cin>>n;
        for(int i=1;i<=n;i++) cin>>a[i];
        for(int i=1;i<=n-1;i++)
        {
            int fa; cin>>fa;
            e[i].v=i+1; cin>>e[i].w;
            G[fa].push_back(i);
        }
    
        dfs(1,-1,-1,0);
    
        F(1);
    
        for(int i=1;i<=n;i++) cout<<ans[i]<<" ";
        cout<<endl;
    
        return 0;
    }
  • 相关阅读:
    电子表单系列谈之纯文本辅助设计表单
    论欧喷索斯应当缓行
    一种用户体验显示对话框时灰化你的主窗体
    程序源代码行数分析统计器
    电子表单系列谈之电子表单基础概念
    通过WebService来使用报表
    使用VBA扩展VS.NET集成开发环境,有Flash演示动画
    Ajax , 好大一颗地雷啊
    发布CHM文档生成器 可替代 HTML Help Workshop,有全部C#源代码
    使用VBA.NET压缩备份C#工程
  • 原文地址:https://www.cnblogs.com/zufezzt/p/6397075.html
Copyright © 2011-2022 走看看