题目

对于 \(50%\) 的数据,\(1<=n<=1000,1<=p<=300\)

对于 \(100%\) 的数据,\(1<=n<=50000,1<=p<=100000,1<=x<=n,0<=k<=1000\)

分析

树上子树加的操作让我们联想到线段树的区间加

然后我们就可以用 \(dfs\) 序把子树弄到序列里

于是考虑怎么加

记根节点深度为 \(0\)

那么让整个子树加 \(k-dep_x\),再有的贡献就是一个节点的深度乘上被加的次数

于是线段树维护即可

\(Code\)

#include<cstdio>
#define LL long long
#define ls (k << 1)
#define rs (ls | 1)
using namespace std; const int N = 5e4 + 5;
int n , p , dfc , tot , dfn[N] , dep[N] , siz[N] , h[N] , rev[N];
LL d[N] , sum[N * 4] , tag_s[N * 4] , tag_c[N * 4];
struct edge{
int to , nxt;
}e[N]; inline void add(int x , int y){e[++tot] = edge{y , h[x]} , h[x] = tot;} void dfs(int x)
{
dfn[x] = ++dfc , rev[dfc] = x , siz[x] = 1;
for(register int i = h[x]; i; i = e[i].nxt)
{
int v = e[i].to;
dep[v] = dep[x] + 1;
dfs(v);
siz[x] += siz[v];
}
} void pushdown(int l , int r , int k)
{
if (tag_s[k] == 0 && tag_c[k] == 0) return;
int mid = (l + r) >> 1;
sum[ls] += tag_s[k] * (mid - l + 1) + tag_c[k] * (d[mid] - d[l - 1]);
tag_s[ls] += tag_s[k] , tag_c[ls] += tag_c[k];
sum[rs] += tag_s[k] * (r - mid) + tag_c[k] * (d[r] - d[mid]);
tag_s[rs] += tag_s[k] , tag_c[rs] += tag_c[k];
tag_s[k] = tag_c[k] = 0;
} void update(int l , int r , int k , int tl , int tr , int v)
{
if (tl <= l && r <= tr)
{
sum[k] += 1LL * (r - l + 1) * v + (d[r] - d[l - 1]);
tag_s[k] += v , tag_c[k] += 1;
return;
}
pushdown(l , r , k);
int mid = (l + r) >> 1;
if (tl <= mid) update(l , mid , ls , tl , tr , v);
if (tr > mid) update(mid + 1 , r , rs , tl , tr , v);
sum[k] = sum[ls] + sum[rs];
} LL query(int l , int r , int k , int tl , int tr)
{
if (tl <= l && r <= tr) return sum[k];
pushdown(l , r , k);
int mid = (l + r) >> 1;
LL res = 0;
if (tl <= mid) res += query(l , mid , ls , tl , tr);
if (tr > mid) res += query(mid + 1 , r , rs , tl , tr);
return res;
} int main()
{
freopen("truetears.in" , "r" , stdin);
freopen("truetears.out" , "w" , stdout);
scanf("%d%d" , &n , &p);
int x , y;
for(register int i = 2; i <= n; i++) scanf("%d" , &x) , add(x , i);
dfs(1);
for(register int i = 1; i <= dfc; i++) d[i] = d[i - 1] + dep[rev[i]];
char opt[5];
for(register int i = 1; i <= p; i++)
{
scanf("%s" , opt);
if (opt[0] == 'A')
{
scanf("%d%d" , &x , &y);
update(1 , n , 1 , dfn[x] , dfn[x] + siz[x] - 1 , y - dep[x]);
}
else {
scanf("%d" , &x);
printf("%lld\n" , query(1 , n , 1 , dfn[x] , dfn[x] + siz[x] - 1));
}
}
}

JZOJ 4895【NOIP2016提高A组集训第16场11.15】三部曲的更多相关文章

  1. JZOJ 【NOIP2016提高A组集训第16场11.15】兔子

    JZOJ [NOIP2016提高A组集训第16场11.15]兔子 题目 Description 在一片草原上有N个兔子窝,每个窝里住着一只兔子,有M条路径连接这些窝.更特殊地是,至多只有一个兔子窝有3 ...

  2. JZOJ 【NOIP2016提高A组集训第16场11.15】SJR的直线

    JZOJ [NOIP2016提高A组集训第16场11.15]SJR的直线 题目 Description Input Output Sample Input 6 0 1 0 -5 3 0 -5 -2 2 ...

  3. 【JZOJ4895】【NOIP2016提高A组集训第16场11.15】三部曲

    =v= 因为外来的入侵,国王决定在某些城市加派士兵.所有城市初始士兵数量为0.当城市 被加派了k名士兵时.城市i的所有子城市需要被加派k+1名士兵.这些子城市的所有子城市需要被加派k+2名士兵.以此类 ...

  4. 【JZOJ4894】【NOIP2016提高A组集训第16场11.15】SJR的直线

    题目描述 数据范围 解法 考虑逐次加入每一条直线. 对于当前已加入的直线集合L,现在要新加入一条直线l. 那么它产生的贡献,与平行线有关. 对于任意三条直线,如果其中任意两条平行,那么将不做贡献. 所 ...

  5. 【JZOJ4896】【NOIP2016提高A组集训第16场11.15】兔子

    题目描述 在一片草原上有N个兔子窝,每个窝里住着一只兔子,有M条路径连接这些窝.更特殊地是,至多只有一个兔子窝有3条或更多的路径与它相连,其它的兔子窝只有1条或2条路径与其相连.换句话讲,这些兔子窝之 ...

  6. 【NOIP2016提高A组集训第4场11.1】平衡的子集

    题目 夏令营有N个人,每个人的力气为M(i).请大家从这N个人中选出若干人,如果这些人可以分成两组且两组力气之和完全相等,则称为一个合法的选法,问有多少种合法的选法? 分析 如果暴力枚举每个人被分到哪 ...

  7. 【NOIP2016提高A组集训第14场11.12】随机游走——期望+树形DP

    好久没有写过题解了--现在感觉以前的题解弱爆了,还有这么多访问量-- 没有考虑别人的感受,没有放描述.代码,题解也写得歪歪扭扭. 并且我要强烈谴责某些写题解的代码不打注释的人,像天书那样,不是写给普通 ...

  8. 【JZOJ4841】【NOIP2016提高A组集训第4场11.1】平衡的子集

    题目描述 夏令营有N个人,每个人的力气为M(i).请大家从这N个人中选出若干人,如果这些人可以分成两组且两组力气之和完全相等,则称为一个合法的选法,问有多少种合法的选法? 数据范围 40%的数据满足: ...

  9. 【NOIP2016提高A组集训第14场11.12】随机游走

    题目 YJC最近在学习图的有关知识.今天,他遇到了这么一个概念:随机游走.随机游走指每次从相邻的点中随机选一个走过去,重复这样的过程若干次.YJC很聪明,他很快就学会了怎么跑随机游走.为了检验自己是不 ...

  10. 【NOIP2016提高A组集训第13场11.11】最大匹配

    题目 mhy12345学习了二分图匹配,二分图是一种特殊的图,其中的点可以分到两个集合中,使得相同的集合中的点两两没有连边. 图的"匹配"是指这个图的一个边集,里面的边两两不存在公 ...

随机推荐

  1. 不用USB,通过adb无线调试安卓手机页面

    以前真机调试手机页面,都是使用数据线连接手机和电脑,近日身边没有USB数据线,折腾了下如何不依赖数据线只用无线调试手机页面,教程如下. 本教程适用于安卓11以及以上版本.否则应该使用USB数据线连接. ...

  2. JavaScript冒泡排序+Vue可视化冒泡动画

    冒泡排序(Bubble Sort)算是前端最简单的算法,也是最经典的排序算法了.网上JavaScript版本的冒泡排序很多,今天用Vue实现一个动态的可视化冒泡排序. 01.JavaScript冒泡排 ...

  3. echarts柱状图渐变色并且显示数据及柱状图的宽度调整

    series: [{ type: 'bar', name: '起飞', barWidth: '20px', //柱状图的宽度 itemStyle: { normal: { //显示渐变色颜色 colo ...

  4. 1、debug调试

    Debug断点调试: Debug调试界面图: 利用Debug功能来追踪代码的运行流程,分析与定位异常发生的位置,观察运行中数据的变化. 1.Step Over(F8):进入下一步,如果当前行断点是一个 ...

  5. [编程基础] Python lambda函数总结

    Python lambda函数教程展示了如何在Python中创建匿名函数.Python中的匿名函数是使用lambda关键字创建的. 文章目录 1 介绍 1.1 简单使用 1.2 Python lamb ...

  6. 第三方模块的下载与使用 requests模块 openpyxl模块

    今日内容 第三方模块下载操作 第三方模块: 别人写的魔魁啊 一般情况下都很强大 python中模块很多 如果想使用第三方模块 第一次必须先下载 后面就可以反复使用 =内置模块 下载第三方模块的方式: ...

  7. vscode快速删除空白行方法

    1.快速打开替换界面,在Find界面输入^\s*(?=\r?$)\n 2.Alt+R选择Use Regular Expression(Alt+R)即正则表达式模式: 3.选择Replace All(C ...

  8. 异常概念&异常体系-异常分类

    异常概念&异常体系 异常,就是不正常的意思.在生活中:医生说,你的身体某个部分有异常,该部位和正常相比有点不同,该部位的功能将受影响,在程序中的意思就是: 异常:指的是程序在执行过程中,出现的 ...

  9. 快速上手python的简单web框架flask

    目录 简介 web框架的重要组成部分 快速上手flask flask的第一个应用 flask中的路由 不同的http方法 静态文件 使用模板 总结 简介 python可以做很多事情,虽然它的强项在于进 ...

  10. Typora软件的使用、编程与编程语言、计算机基础、五大组成部分、三大核心硬件、操作系统

    目录 一.Typora软件的下载与使用 (1).软件下载 (2).markdown语法 二.编程与编程语言 (1).什么是语言 (2).什么是编程 (3).什么是编程语言 三.计算机本质 四.计算机五 ...