On Changing Tree

Time Limit: 2000ms
Memory Limit: 262144KB

This problem will be judged on CodeForces. Original ID: 396C
64-bit integer IO format: %I64d      Java class name: (Any)

 
You are given a rooted tree consisting of n vertices numbered from 1 to n. The root of the tree is a vertex number 1.

Initially all vertices contain number 0. Then come q queries, each query has one of the two types:

  • The format of the query: 1 v x k. In response to the query, you need to add to the number at vertex v number x; to the numbers at the descendants of vertex v at distance 1, addx - k; and so on, to the numbers written in the descendants of vertex v at distance i, you need to add x - (i·k). The distance between two vertices is the number of edges in the shortest path between these vertices.
  • The format of the query: 2 v. In reply to the query you should print the number written in vertex v modulo 1000000007 (109 + 7).

Process the queries given in the input.

Input

The first line contains integer n (1 ≤ n ≤ 3·105) — the number of vertices in the tree. The second line contains n - 1 integers p2, p3, ... pn (1 ≤ pi < i), where pi is the number of the vertex that is the parent of vertex i in the tree.

The third line contains integer q (1 ≤ q ≤ 3·105) — the number of queries. Next q lines contain the queries, one per line. The first number in the line is type. It represents the type of the query. If type = 1, then next follow space-separated integers v, x, k (1 ≤ v ≤ n; 0 ≤ x < 109 + 7; 0 ≤ k < 109 + 7). If type = 2, then next follows integer v (1 ≤ v ≤ n) — the vertex where you need to find the value of the number.

 

Output

For each query of the second type print on a single line the number written in the vertex from the query. Print the number modulo 1000000007 (109 + 7).

 

Sample Input

Input
3
1 1
3
1 1 2 1
2 1
2 2
Output
2
1

Hint

You can read about a rooted tree here: http://en.wikipedia.org/wiki/Tree_(graph_theory).

 

Source

 
解题:树状数组或者线段树
 
给出一棵以1为根的树,形式是从节点2开始给出每个节点的父亲节点;
然后是m次操作,操作分为两种,1 v, x, k,表示在以v为根的字数上添加,添加的法则是看这个节点与v节点的距离为i的话,加上x-i*k;
2 v查询节点v的值。
 
发现相加的性质,维护两个树状数组
 
给c1 结点代表的区间都加上x + d[u]*k 给第二个树状数组也加上 d[u]*k
 
假设u是v的父节点 当计算v的时候 可以用$ x + d[u]*k - d[v]*k $
 
正是我们要的$x + k\times (d[u] - d[v])$
 
 #include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = ;
const int mod = ;
vector<int>g[maxn];
LL c[][maxn],val[];
int n,m,L[maxn],R[maxn],d[maxn],clk;
void update(int i){
while(i < maxn){
c[][i] += val[];
c[][i] += val[];
c[][i] %= mod;
c[][i] %= mod;
i += i&-i;
}
}
LL query(int i){
LL sum[] = {},dep = d[i];
i = L[i];
while(i > ){
sum[] += c[][i];
sum[] += c[][i];
sum[] %= mod;
sum[] %= mod;
i -= i&-i;
}
return ((sum[] - dep*sum[])%mod + mod)%mod;
}
void dfs(int u,int dep){
L[u] = ++clk;
d[u] = dep;
for(int i = g[u].size()-; i >= ; --i)
dfs(g[u][i],dep+);
R[u] = clk;
}
int main(){
int u,op,x,y,z;
while(~scanf("%d",&n)){
for(int i = clk = ; i <= n; ++i) g[i].clear();
for(int i = ; i <= n; ++i){
scanf("%d",&u);
g[u].push_back(i);
}
dfs(,);
memset(c,,sizeof c);
scanf("%d",&m);
while(m--){
scanf("%d%d",&op,&x);
if(op == ){
scanf("%d%d",&y,&z);
val[] = ((LL)y + (LL)d[x]*z)%mod;
val[] = z;
update(L[x]);
val[] = -val[];
val[] = -val[];
update(R[x]+);
}else printf("%I64d\n",query(x));
}
}
return ;
}

CodeForces 396C On Changing Tree的更多相关文章

  1. CodeForces - 396C On Changing Tree(树状数组)

    题目大意 给定一棵以1为根的树,初始时所有点为0 给出树的方式是从节点2开始给出每一个点的父亲 然后是 $m$ 次操作,分为两种 $1 v,k,x$ 表示在以v为根的子树中的每一个点上添加 $x-i* ...

  2. Codeforces 461B Appleman and Tree(木dp)

    题目链接:Codeforces 461B Appleman and Tree 题目大意:一棵树,以0节点为根节点,给定每一个节点的父亲节点,以及每一个点的颜色(0表示白色,1表示黑色),切断这棵树的k ...

  3. CF396C On Changing Tree

    CF396C On Changing Tree 给定一棵以 \(1\) 为根的树,初始时所有点权为 \(0\) 有 \(m\) 次操作,分为两种 \(1\ u\ x\ k\) 表示给以 \(u\) 的 ...

  4. Codeforces 1129 E.Legendary Tree

    Codeforces 1129 E.Legendary Tree 解题思路: 这题好厉害,我来复读一下官方题解,顺便补充几句. 首先,可以通过询问 \(n-1​\) 次 \((S=\{1\},T=\{ ...

  5. Codeforces 280C Game on tree【概率DP】

    Codeforces 280C Game on tree LINK 题目大意:给你一棵树,1号节点是根,每次等概率选择没有被染黑的一个节点染黑其所有子树中的节点,问染黑所有节点的期望次数 #inclu ...

  6. Codeforces A. Game on Tree(期望dfs)

    题目描述: Game on Tree time limit per test 1 second memory limit per test 256 megabytes input standard i ...

  7. Codeforces Round #781(C. Tree Infection)

    Codeforces Round #781 C. Tree Infection time limit per test 1 second memory limit per test 256 megab ...

  8. Codeforces 734E. Anton and Tree 搜索

    E. Anton and Tree time limit per test: 3 seconds memory limit per test :256 megabytes input:standard ...

  9. codeforces 161D Distance in Tree 树形dp

    题目链接: http://codeforces.com/contest/161/problem/D D. Distance in Tree time limit per test 3 secondsm ...

随机推荐

  1. oc31--new实现

    // // main.m // new方法实现原理 #import <Foundation/Foundation.h> #import "Person.h" int m ...

  2. javascript从作用域链的角度看闭包

    闭包 闭包是一个能访问外部函数定义的变量的函数. 为什么? 当访问一个变量时,解释器会首先在当前作用域查找标示符,如果没有找到,就去父作用域找,直到找到该变量的标示符或者不再存在父作用域了,这就是作用 ...

  3. go的基础数据类型

    一.基础数据类型 在go语言中,数据类型用于申明函数和变量 go语言的类型 数据类型 描述 布尔型 布尔型值的只能是true 和 false ,例如 var b bool = true, 布尔型值声明 ...

  4. 微信js sdk上传多张图片

    微信js sdk上传多张图片,微信上传多张图片 该案例已tp3.2商城为例 直接上代码: php代码: public function ind(){ $appid="111111111111 ...

  5. sublime text 快键键

    sublime text 的快捷键ctrl+l                              选择整行(按住-继续选择下行)ctrl+shift+k                    ...

  6. 5.17领扣--Arrays.copyOf()方法

    ?? 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标. 你可以假设每种输入只会对应一个答案.但是,你不能重复利用这个数组中同 ...

  7. HttpServletResponse对象,自己学习的心得

    Web服务器收到客户端的http请求,会针对每一次请求,分别创建一个用于代表请求的request对象,和代表响应response对象. request和response对象既然代表请求和响应,那我们要 ...

  8. 易企CMS主要模板文件介绍

    article.tpl 文章内容页模板 catalog.tpl 文章,产品目录页模板 category.tpl 分类页模板 comment.tpl 留言页模板 footer.tpl 页尾模板 head ...

  9. ThreadPoolExecutor理解

    ThreadPoolExecutor组成 ThreadPoolExecutor的核心构造函数: public ThreadPoolExecutor(int corePoolSize, int maxi ...

  10. html5 web worker学习笔记(记一)

    (吐槽:浏览器js终于进入多线程时代!) 以前利用setTimeout.setInterval等方式的多线程,是伪多线程,本质上是一种在单线程中进行队列执行的方式.自从html5 web worker ...