首页 > 其他 > 详细

CodeForces 740D Alyona and a tree

时间:2017-02-14 13:26:29      阅读:153      评论:0      收藏:0      [点我收藏+]

倍增,延迟标记。

考虑一个$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;
}

 

CodeForces 740D Alyona and a tree

原文:http://www.cnblogs.com/zufezzt/p/6397075.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!