On Changing Tree

CodeForces - 396C

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 vat distance 1, add x - 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 qlines 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).

Examples

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

Note

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

给出一棵以1为根的树,形式是从节点2开始给出每个节点的父亲节点;
然后是m次操作,操作分为两种,1 v, x, k,表示在以v为根的子树上添加,
添加的法则是看这个节点与v节点的距离为i的话,加上x-i*k;2 v查询节点v的值。

sol:子树操作显然可以搞出dfs序然后修改一段区间,然后修改是一个经典操作,看做是子树每个节点加上x+deg[v]*k,查询y的时候减去dep[y]*k即可

/*
给出一棵以1为根的树,形式是从节点2开始给出每个节点的父亲节点;
然后是m次操作,操作分为两种,1 v, x, k,表示在以v为根的子树上添加,
添加的法则是看这个节点与v节点的距离为i的话,加上x-i*k;2 v查询节点v的值。
*/
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
inline ll read()
{
ll s=;
bool f=;
char ch=' ';
while(!isdigit(ch))
{
f|=(ch=='-'); ch=getchar();
}
while(isdigit(ch))
{
s=(s<<)+(s<<)+(ch^); ch=getchar();
}
return (f)?(-s):(s);
}
#define R(x) x=read()
inline void write(ll x)
{
if(x<)
{
putchar('-'); x=-x;
}
if(x<)
{
putchar(x+''); return;
}
write(x/);
putchar((x%)+'');
return;
}
#define W(x) write(x),putchar(' ')
#define Wl(x) write(x),putchar('\n')
const int N=,M=;
const ll Mod=;
int n,Q;
inline void Ad(ll &x,ll y)
{
x+=y; x-=(x>=Mod)?Mod:; x+=(x<)?Mod:;
}
namespace Tree
{
int tot=,Next[M],to[M],head[N];
inline void add(int x,int y)
{
Next[++tot]=head[x];
to[tot]=y;
head[x]=tot;
}
int In[N],Out[N],cnt=,Depth[N];
inline void dfs(int x)
{
int i;
In[x]=++cnt;
for(i=head[x];i;i=Next[i]) Depth[to[i]]=Depth[x]+,dfs(to[i]);
Out[x]=++cnt;
}
struct segment
{
ll S[N<<];
#define lowbit(x) ((x)&(-x))
inline void Ins(int x,int Val)
{
while(x<=cnt)
{
Ad(S[x],Val); x+=lowbit(x);
}
}
inline int Que(int x)
{
ll ans=;
while(x>)
{
Ad(ans,S[x]); x-=lowbit(x);
}
return ans;
}
}SGT[];
inline void Solve()
{
int i;
Depth[]=; dfs();
R(Q);
while(Q--)
{
ll opt,rt,Val,Del;
R(opt); R(rt);
if(opt==)
{
Val=read()%Mod; R(Del);
SGT[].Ins(In[rt],(Val+Del*Depth[rt]%Mod)%Mod);
SGT[].Ins(Out[rt]+,(-)*(Val+Del*Depth[rt]%Mod)%Mod);
SGT[].Ins(In[rt],Del);
SGT[].Ins(Out[rt]+,(-)*Del);
}
else
{
ll tmp,oo;
tmp=SGT[].Que(In[rt]);
oo=SGT[].Que(In[rt]);
Ad(tmp,(-)*oo*Depth[rt]%Mod);
Wl(tmp);
}
}
}
}
#define T Tree
int main()
{
int i;
R(n);
for(i=;i<=n;i++)
{
int x=read(); T::add(x,i);
}
T::Solve();
return ;
}
/*
Input
3
1 1
3
1 1 2 1
2 1
2 2
Output
2
1 Input
10
1 2 3 4 4 3 3 6 7
10
1 6 13 98
1 7 17 66
1 5 32 39
1 1 9 5
1 7 27 11
1 1 24 79
1 5 87 86
2 2
1 5 9 38
2 5
Output
999999956
999999832
*/

codeforces396C的更多相关文章

随机推荐

  1. git bash push 本地的commit到远程 -- ssh keys设置

    1.  检查是否已经创建 ssh keys git bash 下,cd ~/.ssh 如何出现“No such file or directory”,则表示需要创建一个ssh keys. 2. 创建新 ...

  2. 【Java】接口和抽象类总结

    一.接口 1.1 成员变量(其实是常量) 1.2 方法 二.抽象类 2.1 成员变量 2.2 方法 一.接口 1.1 成员变量(其实是常量) 成员变量默认用 public static final修饰 ...

  3. 基于FTP 的本地Yum服务器配置

    服务器端 环境如下 Vmware14CentOS 7.6 192.168.20.81 server 192.168.20.81 client 1.配置yum源 mount /dev/cdrom /me ...

  4. python与mysql的数据交互

    一 Python 中操作 MySQL 步骤 1.1 安装pymysql命令 sudo pip3 install pymysql 安装软件:sudo apt-get install 软件名称 安装模块: ...

  5. [Jenkins][GitHub]2 持续集成环境初探

    预计阅读时间:30分钟 部署环境:Jenkins ver. 2.61 + Centos7 + Java 1.8 参考链接: http://www.jianshu.com/p/22b7860b4e81 ...

  6. 使用Ponysay,在Linux终端显示彩虹小马

    Ponysay类似于Cowsay,可以在终端打印所有小马的像素画.还有个ponythink,这个是小马想,那个是小马说,效果如下: 安装: sudo apt-get install ponysay 使 ...

  7. nn.Conv2d 参数及输入输出详解

    Torch.nn.Conv2d(in_channels,out_channels,kernel_size,stride=1,padding=0,dilation=1,groups=1,bias=Tru ...

  8. Crossover 19(Mac运行Windows应用程序)

    怎样才能在Mac上运行Windows应用程序?相信这是很多朋友都在问的问题,今天macdown(mac软件平台)小编为大家带来Crossover 19 Mac版下载,Crossover 19 mac版 ...

  9. docker 安装elk

    https://www.cnblogs.com/fbtop/p/11005469.html

  10. 2019招商银行M-Geeker线上比赛题解析

    目录 1. 最大子序和(变体) 2. 矩阵求乘积最大 3. 逐渐平均--值最大 目前已更新:第一题,第二题,第四题 1. 最大子序和(变体) 题目描述: 首先考虑常规的最大子序和的问题,即不能去掉中间 ...