嘟嘟嘟

前缀和+倍增+树上差分

假设\(v\)是\(u\)子树中的一个点,那么\(u\)能控制\(v\)的条件是受\(v\)的权值的限制,而并非\(u\)。因此我们就能想到计算每一个点的贡献,即\(v\)有多少个祖先能控制它。这样就能想到暴力的做法:枚举每一个点\(i\),向上爬直到两点间距离大于\(a_i\)为止。然后树上差分(准确说是链上差分)即可。至于两点间距离,采用前缀和相减。

但这样的复杂度能达到\(O(n^2)\),因此我们可以用倍增优化一步步向上跳,达到\(O(nlogn)\)。

总结一下,先\(dfs\)一遍求出每一个点到根节点的距离和差分数组,复杂度\(O(nlogn)\);然后对于每一个点倍增向上跳,并修改差分数组,复杂度也是\(O(nlogn)\);最后\(O(n)\) \(dfs\)一遍求查差分组的树上前缀和。

#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<cctype>
#include<vector>
#include<stack>
#include<queue>
using namespace std;
#define enter puts("")
#define space putchar(' ')
#define Mem(a, x) memset(a, x, sizeof(a))
#define rg register
typedef long long ll;
typedef double db;
const int INF = 0x3f3f3f3f;
const db eps = 1e-8;
const int maxn = 2e5 + 5;
inline ll read()
{
ll ans = 0;
char ch = getchar(), last = ' ';
while(!isdigit(ch)) last = ch, ch = getchar();
while(isdigit(ch)) ans = (ans << 1) + (ans << 3) + ch - '0', ch = getchar();
if(last == '-') ans = -ans;
return ans;
}
inline void write(ll x)
{
if(x < 0) x = -x, putchar('-');
if(x >= 10) write(x / 10);
putchar(x % 10 + '0');
} int n;
ll a[maxn];
struct Edge
{
int nxt, to, w;
}e[maxn];
int head[maxn], ecnt = -1;
void addEdge(int x, int y, int w)
{
e[++ecnt] = (Edge){head[x], y, w};
head[x] = ecnt;
} int fa[21][maxn];
ll dis[maxn];
void dfs(int now)
{
for(int i = 1; i <= 20; ++i)
fa[i][now] = fa[i - 1][fa[i - 1][now]];
for(int i = head[now], v; i != -1; i = e[i].nxt)
{
v = e[i].to;
fa[0][v] = now;
dis[v] = dis[now] + e[i].w;
dfs(v);
}
} int dif[maxn];
void solve(int now)
{
int x = now;
for(int i = 20; i >= 0; --i)
if(fa[i][x] && dis[now] - dis[fa[i][x]] <= a[now]) x = fa[i][x];
if(x != 1) dif[fa[0][x]]--;
if(now != 1) dif[fa[0][now]]++;
} void dfs2(int now)
{
for(int i = head[now], v; i != -1; i = e[i].nxt)
{
v = e[i].to;
dfs2(v);
dif[now] += dif[v];
}
} int main()
{
Mem(head, -1);
n = read();
for(int i = 1; i <= n; ++i) a[i] = read();
for(int i = 2; i <= n; ++i)
{
int x = read(), w = read();
addEdge(x, i, w);
}
dfs(1);
for(int i = 1; i <= n; ++i) solve(i);
dfs2(1);
for(int i = 1; i <= n; ++i) write(dif[i]), space; enter;
return 0;
}

CF739B Alyona and a tree的更多相关文章

  1. Codeforces Round #381 (Div. 2)D. Alyona and a tree(树+二分+dfs)

    D. Alyona and a tree Problem Description: Alyona has a tree with n vertices. The root of the tree is ...

  2. codeforces 381 D Alyona and a tree(倍增)(前缀数组)

    Alyona and a tree time limit per test 2 seconds memory limit per test 256 megabytes input standard i ...

  3. Codeforces Round #381 (Div. 1) B. Alyona and a tree dfs序 二分 前缀和

    B. Alyona and a tree 题目连接: http://codeforces.com/contest/739/problem/B Description Alyona has a tree ...

  4. Codeforces Round #381 (Div. 2) D. Alyona and a tree 树上二分+前缀和思想

    题目链接: http://codeforces.com/contest/740/problem/D D. Alyona and a tree time limit per test2 secondsm ...

  5. CodeForces 682C Alyona and the Tree (树+dfs)

    Alyona and the Tree 题目链接: http://acm.hust.edu.cn/vjudge/contest/121333#problem/C Description Alyona ...

  6. Alyona and a tree

    Alyona and a tree time limit per test 2 seconds memory limit per test 256 megabytes input standard i ...

  7. Codeforces Round #358 (Div. 2) C. Alyona and the Tree 水题

    C. Alyona and the Tree 题目连接: http://www.codeforces.com/contest/682/problem/C Description Alyona deci ...

  8. Codeforces Round #381 (Div. 2) D. Alyona and a tree dfs序+树状数组

    D. Alyona and a tree time limit per test 2 seconds memory limit per test 256 megabytes input standar ...

  9. Codeforces Round #358 (Div. 2) C. Alyona and the Tree dfs

    C. Alyona and the Tree time limit per test 1 second memory limit per test 256 megabytes input standa ...

随机推荐

  1. 文档转换为pdf格式帮助类

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using Word = M ...

  2. Java复习第一天

    Day01 1.独立编写Hello World程序. public class Test{ public static void main(String[] args){ System.out.pri ...

  3. Oracle 数据库字典 sys.obj$ 表中关于type#的解释

    sys.obj$ 表是oracle 数据库字典表中的对象基础表,所有对象都在该表中有记录,其中type#字段表明对象类型,比如有一个表 test ,则该对象在sys.obj$ 中存在一条记录,name ...

  4. Java温故而知新(4)类String字符串

    字符串是由字符组成,在Java中,字符串是对象,是描述字符的基本数据结构.String类可以用来保存一个字符串,本类是最终类,不允许继承: 1.String对象的创建 初始化 由于String对象特别 ...

  5. FusionCharts数据展示成饼状图、柱状图和折线图

    FusionCharts数据展示成饼状图.柱状图和折线图 本文以展示柱状图为例进行介绍,当然这仅仅是一种方法而已:还有很多方法可以用于展示图表,例如echarts,自定义图表标签.使用jfreecha ...

  6. influxdb 端口、数据结构、写数据

    InfluxDB 是一个开源,分布式,时间序列,事件,可度量和无外部依赖的数据库. InfluxDB有三大特性: Time Series (时间序列):你可以使用与时间有关的相关函数(如最大,最小,求 ...

  7. PL/SQL: numeric or value error: character to number conversion error

    在最简单的plsql块编程中出现这个错误,是因为 DBMS_OUTPUT.PUT_LINE('the x is '+x);这里面不能用“+”,而是要用“||” DECLARE x number; ; ...

  8. php获取今日开始时间和结束时间

    $begintime=date("Y-m-d H:i:s",mktime(0,0,0,date('m'),date('d'),date('Y'))); $endtime=date( ...

  9. csharp:qq weather

    using System; using System.Data; using System.Configuration; using System.Collections; using System. ...

  10. jquery not() 方法

    1.not(expression) 根据表达式参数的值,从包装集里删除元素 example : $('img[alt]').not('[alt*=joy]') 返回包含属性alt的img元素,但img ...