[Usaco2012 Dec]Running Away From the Barn

Title Description

1 point is given as a rooted tree root, ask each point in the subtree and its distance is less than equal to the number of points l.

Input Format

Line 1: 2 integers, N and L (1 <= N <= 200,000, 1 <= L <= 10^18)

Lines 2..N: The ith line contains two integers p_i and l_i. p_i (1 <= p_i < i) is the first pasture on the shortest path between pasture i and the barn, and l_i (1 <= l_i <= 10^12) is the length of that path.

Output Format

Lines 1..N: One number per line, the number on line i is the number pastures that can be reached from pasture i by taking roads that lead strictly farther away from the barn (pasture 1) whose total length does not exceed L.


This question has many advanced practiceBut I will not

We analyzed the topic can come to a conclusion - for the current node u, u sub-tree in the distance u l greater than the distance of the point of all ancestors are greater than u l (u also their ancestors). So easy to think of us for each node u, we first calculate a distance greater than its ancestors anc u l, then for the ancestors, its answer will subtract size (u). Nodes represent sub-tree size, the answer to initialize each point of the child nodes of the tree. The resulting binding properties before then, we can use the prefix tree and thought, this subtracted size (u) anc ancestors accumulated to go.

But you will find that direct regarded as problematic.

First for u, it anc do is answer -size (u) of the contribution, and the contribution we want to accumulate anc ancestors go. Then we found that for u ancestors, such as the father of u fa (u), the first and fa (u) is greater than the distance l ancestors must have been anc ancestors, but we will -size (fa (u)) plus to this ancestor, that is the ancestor of the answer accumulate twice -size (u), the answer is obviously wrong. How to avoid it? Quite simply, we will size (fa (u)) minus the size (u) can be. Then the problem is solved.

For the seeking is greater than the first distance l ancestor, we can do multiplication, then the total time complexity is O (NlogN).

* The size (fa (u)) is subtracted size (u) the original size, at which point size (u) may have been minus some child node u, so we again open array to a record size the original size.

* Do not open long long to see fathers

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#define maxn 200001
using namespace std;
 
struct edge{
    int to,next; long long dis;
    edge(){}
    edge(const int &_to,const long long &_dis,const int &_next){ to=_to,dis=_dis,next=_next; }
}e[maxn<<1];
int head[maxn],k;
 
int fa[maxn][20],size[maxn],size2[maxn],sum[maxn],maxdep;
int n;
long long m,dis[maxn][20];
 
inline long long read(){
    register long long x(0),f(1); register char c(getchar());
    while(c<'0'||'9'<c){ if(c=='-') f=-1; c=getchar(); }
    while('0'<=c&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
    return x*f;
}
inline void add(const int &u,const int &v,const long long &w){ e[k]=edge(v,w,head[u]),head[u]=k++; }
 
void dfs(int u){
    size[u]=1;
    for(register int i=head[u];~i;i=e[i].next){
        int v=e[i].to;
        if(v==fa[u][0]) continue;
        fa[v][0]=u,dis[v][0]=e[i].dis;
        for(register int j=1;j<=maxdep;j++) fa[v][j]=fa[fa[v][j-1]][j-1],dis[v][j]=dis[v][j-1]+dis[fa[v][j-1]][j-1];
        dfs(v),size[u]+=size[v];
    }
}
 
void dfs_getsum(int u){
    for(register int i=head[u];~i;i=e[i].next){
        int v=e[i].to;
        if(v==fa[u][0]) continue;
        dfs_getsum(v);
        long long len=0; int tmp=size[v],tmp2=size2[v];
        for(register int j=maxdep;j>=0;j--) if(len+dis[v][j]<=m&&fa[v][j]) len+=dis[v][j],v=fa[v][j];
        if(len+dis[v][0]>m&&fa[v][0]) sum[fa[v][0]]+=tmp,size[u]-=tmp2;
    }
}
 
void dfs_getans(int u){
    for(register int i=head[u];~i;i=e[i].next){
        int v=e[i].to;
        if(v==fa[u][0]) continue;
        dfs_getans(v),sum[u]+=sum[v];
    }
}
 
int main(){
    memset(head,-1,sizeof head);
    n=read(),m=read();
    for(register int i=2;i<=n;i++){
        int v=read(); long long w=read();
        add(i,v,w),add(v,i,w);
    }
    maxdep=(int)log(n)/log(2),dfs(1);
    for(register int i=1;i<=n;i++) size2[i]=size[i];
     
    dfs_getsum(1);
    dfs_getans(1);
     
    for(register int i=1;i<=n;i++) printf("%d\n",size2[i]-sum[i]);
    return 0;
}

Guess you like

Origin www.cnblogs.com/akura/p/10945606.html