题目大意

给定一棵以1为根的树,初始时所有点为0

给出树的方式是从节点2开始给出每一个点的父亲

然后是 $m$ 次操作,分为两种

$1 v,k,x$ 表示在以v为根的子树中的每一个点上添加 $x-i*k$( $i$ 表示节点与 $v$ 的距离)(包括点 $v$ )

$2 v$ 查询节点 $v$ 的值

输出每一个2操作的答案模 $1e9+7$ 的值

题解

话说真没想到这题竟然这么简单……死活都想不出来……

先dfs预处理出每一个节点的dfs序,以及子树代表的区间$ls$和$rs$,以及每一个点的深度$dep$

假设先$add(ls[v],x+dep[v]*k),add(rs[v]+1,-x-dep[v]*k)$,然后用树状数组维护前缀和,树状数组设为$c1$

可以发现,$v$这个点多加去了$dep[v]*k$,要减掉。同理可得,$v$的所有子树都要减掉$dep[j]*k$($j$为$v$的子节点)

可以证明以上这么乱搞之后每一个点的值都加上了正确的数

乱证:$j$节点经过这一操作后加上了$dep[v]*k-dep[j]*k=k*(dep[j]-dep[v])=k*dis[v,j]$

然后证明每一个节点都加上了正确的数值

那么只要再开一个树状数组维护前缀$k$就可以了

查询的答案就是$sum(ls[v],c1)-sum(ls[v],c2)*dep[v]$

 //minamoto
#include<iostream>
#include<cstdio>
#define ll long long
using namespace std;
#define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
char buf[<<],*p1=buf,*p2=buf;
inline int read(){
#define num ch-'0'
char ch;bool flag=;int res;
while(!isdigit(ch=getc()))
(ch=='-')&&(flag=true);
for(res=num;isdigit(ch=getc());res=res*+num);
(flag)&&(res=-res);
#undef num
return res;
}
char sr[<<],z[];int C=-,Z;
inline void Ot(){fwrite(sr,,C+,stdout),C=-;}
inline void print(ll x){
if(C><<)Ot();if(x<)sr[++C]=,x=-x;
while(z[++Z]=x%+,x/=);
while(sr[++C]=z[Z],--Z);sr[++C]='\n';
}
const int N=,mod=1e9+;
int ver[N],head[N],Next[N],dep[N];
int ls[N],rs[N];
ll c[][N];
int n,tot,q,cnt;
inline void add(int x,ll val,int k){
for(int i=x;i<=n;i+=i&(-i))
(c[k][i]+=val)%=mod;
}
inline ll sum(int x){
ll a=,b=;
for(int i=ls[x];i;i-=i&(-i)){
a+=c[][i],b+=c[][i];
}
return ((a-b*dep[x])%mod+mod)%mod;
}
void dfs(int u,int fa){
ls[u]=++cnt;
dep[u]=dep[fa]+;
for(int i=head[u];i;i=Next[i]) dfs(ver[i],u);
rs[u]=cnt;
}
int main(){
//freopen("testdata.in","r",stdin);
n=read();
for(int i=;i<=n;++i){
int fa=read();
ver[++tot]=i,Next[tot]=head[fa],head[fa]=tot;
}
dfs(,);
q=read();
while(q--){
int opt=read(),v=read();
if(opt&) print(sum(v));
else{
ll x=read(),k=read();
add(ls[v],x+dep[v]*k,);
add(rs[v]+,-x-dep[v]*k,);
add(ls[v],k,);
add(rs[v]+,-k,);
}
}
Ot();
return ;
}

CodeForces - 396C On Changing Tree(树状数组)的更多相关文章

  1. CodeForces 396C On Changing Tree

    On Changing Tree Time Limit: 2000ms Memory Limit: 262144KB This problem will be judged on CodeForces ...

  2. codeforces#1167F. Scalar Queries(树状数组+求贡献)

    题目链接: https://codeforces.com/contest/1167/problem/F 题意: 给出长度为$n$的数组,初始每个元素为$a_i$ 定义:$f(l, r)$为,重排$l$ ...

  3. HDU3333 Turing Tree 树状数组+离线处理

    Turing Tree Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  4. POJ 3321 Apple Tree(树状数组)

                                                              Apple Tree Time Limit: 2000MS   Memory Lim ...

  5. HDU 3333 - Turing Tree (树状数组+离线处理+哈希+贪心)

    题意:给一个数组,每次查询输出区间内不重复数字的和. 这是3xian教主的题. 用前缀和的思想可以轻易求得区间的和,但是对于重复数字这点很难处理.在线很难下手,考虑离线处理. 将所有查询区间从右端点由 ...

  6. POJ--3321 Apple Tree(树状数组+dfs(序列))

    Apple Tree Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 22613 Accepted: 6875 Descripti ...

  7. CodeForces 828E DNA Evolution(树状数组)题解

    题意:给你一个串k,进行两个操作: “1 a b”:把a位置的字母换成b “2 l r s”:求l到r有多少个字母和s匹配,匹配的条件是这样:从l开始无限循环s形成一个串ss,然后匹配ss和指定区间的 ...

  8. Codeforces 909C Python Indentation:树状数组优化dp

    题目链接:http://codeforces.com/contest/909/problem/C 题意: Python是没有大括号来标明语句块的,而是用严格的缩进来体现. 现在有一种简化版的Pytho ...

  9. gym 100589A queries on the Tree 树状数组 + 分块

    题目传送门 题目大意: 给定一颗根节点为1的树,有两种操作,第一种操作是将与根节点距离为L的节点权值全部加上val,第二个操作是查询以x为根节点的子树的权重. 思路: 思考后发现,以dfs序建立树状数 ...

随机推荐

  1. 移动端web页面input限制只能输入数字

    <input type="number" pattern="[0-9]*" /> 如上所示,在安卓端设置input类型为number,可限制键盘只输 ...

  2. uml 时序图

    1.时序图的概念 时序图定义 : 描述了对象之间传递消息的时间顺序, 用来表示用例中的行为顺序, 是强调消息时间顺序的交互图; 时序图描述的事物: 时序图描述系统中类和类之间的交互, 将这些交互建模成 ...

  3. java算法 第七届 蓝桥杯B组(题+答案) 4.分小组

    4.分小组  (代码填空) 9名运动员参加比赛,需要分3组进行预赛.有哪些分组的方案呢? 我们标记运动员为 A,B,C,... I下面的程序列出了所有的分组方法. 该程序的正常输出为:ABC DEF ...

  4. DPDK收发包全景分析

    前言:DPDK收发包是基础核心模块,从网卡收到包到驱动把包拷贝到系统内存中,再到系统对这块数据包的内存管理,由于在处理过程中实现了零拷贝,数据包从接收到发送始终只有一份,对这个报文的管理在前面的mem ...

  5. easyui图标大全

    .icon-blank{ background:url('icons/blank.gif') no-repeat; } .icon-add{ background:url('icons/edit_ad ...

  6. N-Gram的数据结构

    ARPA的n-gram语法如下: [html] view plaincopyprint? \data\ ngram 1=64000 ngram 2=522530 ngram 3=173445 \1-g ...

  7. Mosquitto 单向SSL配置

    Mosquitto 单向SSL配置 摘自:https://blog.csdn.net/a_bcd_123/article/details/70167833 2017年04月14日 06:56:06 s ...

  8. 1.单机部署hadoop测试环境

    之前看了很多理论上的知识,感觉云里雾里的,所以赶紧着手搭建个单机版的hadoop跑一跑,开启自学大数据技术的第一步~~ 1.在开源的世界里,我就是个土豪,要啥有啥,所以首先你得有个jdk,有钱所以用最 ...

  9. vim在linux下中如何设置显示行数

    在.vimrc(或/etc/vimrc)文件中输入如下文本: set tabstop=4  set softtabstop=4  set shiftwidth=4  set noexpandtab  ...

  10. MicroRNA 详解

    MicroRNA研究历史和方法   Views 88 1Report