概述
链接:http://codeforces.com/contest/739/problem/B
思路: 还算是比较简单的一个倍增,我们可以预处理出来节点u的2的j 次方父亲和他到2的j次方父亲的距离,然后就是枚举每个点找到他能作用的父亲区间,当然他能作用的父亲左区间肯定是他的直接父亲,右区间对应一个祖先,那么我对于直接父亲+1 右区间父亲的直接父亲-1 然后就是dfs 统计答案。
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int ,ll >pil;
const ll inf =1e15;
const int N =2e5+5;
ll val[N];
ll dep[N];
int fa[N];
vector< pil >ve[N];
int n;
int anc[N][23];
ll dis[N][23];
int book[N];
void bfs()
{
fa[0]=0;
fa[1]=0;
for(int i=0;i<=n;i++)
{
anc[i][0]=fa[i];
}
for(int j=1;(1<<j)<=n;j++)
{
for(int i=0;i<=n;i++)
{
anc[i][j]=anc[anc[i][j-1]][j-1];
}
}
for(int i=0;i<=n;i++)
{
for(int j=0;j<=21;j++)
{
int ac=anc[i][j];
dis[i][j]=dep[i]-dep[ac];
}
}
}
void dfs(int u,ll deep)
{
dep[u]=deep;
for(int i=0;i<ve[u].size();i++)
{
int v=ve[u][i].first;
dfs(v,deep+ve[u][i].second);
}
}
int ans[N];
void dfs2(int u)
{
for(int i=0;i<ve[u].size();i++)
{
int v=ve[u][i].first;
dfs2(v);
book[u]+=book[v];
}
ans[u]=book[u];
}
int main()
{
int u,v; ll w;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%lld",&val[i]);
}
for(v=2;v<=n;v++)
{
scanf("%d %lld",&u,&w);
ve[u].push_back(pil(v,w));
fa[v]=u;
}
ve[0].push_back(pil(1,1e15));
dfs(0,0);
bfs();
/*
printf("********n");
for(int i=0;i<=n;i++)
{
for(int j=0;j<=5;j++)
{
printf("%d ",anc[i][j]);
}
printf("n");
}
printf("********n");
for(int i=0;i<=n;i++)
{
for(int j=0;j<=21;j++)
{
printf("%lld ",dis[i][j]);
}
printf("n");
}
*/
for(int i=2;i<=n;i++)
{
ll aim=val[i];
int j;
u=i;
for(j=21;j>=0;j--)
{
if(anc[u][j]==0||dis[u][j]>aim) continue;
aim-=dis[u][j];
u=anc[u][j];
}
int st=anc[i][0];
int en=anc[u][0];
book[st]++;
book[en]--;
// printf("**** i %d st %d en %d n",i,st,en);
}
dfs2(0);
for(int i=1;i<=n;i++)
{
printf("%d ",ans[i]);
}
return 0;
}
/*
9
1 2 3 4 5 6 7 8 9
1 1
2 1
3 1
4 1
5 1
6 1
7 1
8 1
*/
最后
以上就是爱撒娇蛋挞为你收集整理的codeforces 739B Alyona and a tree的全部内容,希望文章能够帮你解决codeforces 739B Alyona and a tree所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复