• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

CodeForces396COnChangingTree

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

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: 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: 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 ≤ n0 ≤ 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])$
 
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long LL;
 4 const int maxn = 300010;
 5 const int mod = 1000000007;
 6 vector<int>g[maxn];
 7 LL c[2][maxn],val[2];
 8 int n,m,L[maxn],R[maxn],d[maxn],clk;
 9 void update(int i){
10     while(i < maxn){
11         c[0][i] += val[0];
12         c[1][i] += val[1];
13         c[0][i] %= mod;
14         c[1][i] %= mod;
15         i += i&-i;
16     }
17 }
18 LL query(int i){
19     LL sum[2] = {0},dep = d[i];
20     i = L[i];
21     while(i > 0){
22         sum[0] += c[0][i];
23         sum[1] += c[1][i];
24         sum[0] %= mod;
25         sum[1] %= mod;
26         i -= i&-i;
27     }
28     return ((sum[0] - dep*sum[1])%mod + mod)%mod;
29 }
30 void dfs(int u,int dep){
31     L[u] = ++clk;
32     d[u] = dep;
33     for(int i = g[u].size()-1; i >= 0; --i)
34         dfs(g[u][i],dep+1);
35     R[u] = clk;
36 }
37 int main(){
38     int u,op,x,y,z;
39     while(~scanf("%d",&n)){
40         for(int i = clk = 0; i <= n; ++i) g[i].clear();
41         for(int i = 2; i <= n; ++i){
42             scanf("%d",&u);
43             g[u].push_back(i);
44         }
45         dfs(1,0);
46         memset(c,0,sizeof c);
47         scanf("%d",&m);
48         while(m--){
49             scanf("%d%d",&op,&x);
50             if(op == 1){
51                 scanf("%d%d",&y,&z);
52                 val[0] = ((LL)y + (LL)d[x]*z)%mod;
53                 val[1] = z;
54                 update(L[x]);
55                 val[0] = -val[0];
56                 val[1] = -val[1];
57                 update(R[x]+1);
58             }else printf("%I64d\n",query(x));
59         }
60     }
61     return 0;
62 }
View Code

 


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
Visual Studio 2013 Preview对C++11的支持发布时间:2022-07-14
下一篇:
C#Css/Js静态文件压缩--Yui.Compressor.Net发布时间:2022-07-14
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap