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. .ajaxStart() / .ajaxStop() —— ajax请求开始时 / 结束时触发

    一..ajaxStart()——ajax请求开始时触发  描述:ajax请求开始时触发 .ajaxStart()的回调函数,全局的,所有的ajax都可以用 写法:元素.ajaxStart(functi ...

  2. Python之原始数据-1

    一.数据对于模型来说是基础,是数据成就了模型,而现在的又是一个数据时代,比如:淘宝等.通过对用户数据的分析挖掘,预测用户的消费习惯等,再比如:人工智能.通过提取摄像头的图片帧数,通过分析图片,得出具体 ...

  3. sql 语句实现一串数字位数不足在左侧补0的技巧

    https://www.cnblogs.com/mylydg/p/5725189.html 在日常使用sql做查询插入操作时,我们通常会用到用sql查询一串编号,这串编号由数字组成.为了统一美观,我们 ...

  4. ivew数控件Tree自定义节点内容示例分析

    ivew数控件Tree自定义节点内容示例分析 demo地址:https://run.iviewui.com/plcWlM4H <template> <Tree :data=" ...

  5. js入门之DOM动态创建数据

    一. 知识点回顾 1. DOM结构 nodeName: '' 标签名 nodeType: '' 类型 1元素节点 2属性节点 3文本节点 nodeValue: '' 如果是元素节点 nodeValue ...

  6. vue 将时间戳转换成日期格式 (一)

    (1)创建一个处理时间格式的js,内容如下: ../../utils/formatDate.js export function formatDate(date, fmt) { if (/(y+)/. ...

  7. php中的特殊标签

    参考:https://www.freebuf.com/column/212586.html 今天看到这篇文章讲到了ctf中的一些关于php标签的小姿势,我虽然不打ctf,但是平常做php的代码审计也经 ...

  8. python使用Pyinstaller打包

    一.前言 python文件打包,将.py文件转化成.exe文件(windows平台),可以使用Pyinstaller来打包 Pyinstaller可以在全平台下使用,但是请注意打包生成的文件不能在全平 ...

  9. 虹软人脸识别 - faceId及IR活体检测的更新介绍

    虹软人脸识别 - faceId及IR活体检测的介绍 前几天虹软推出了 Android ArcFace 2.2版本的SDK,相比于2.1版本,2.2版本中的变化如下: VIDEO模式新增faceId(类 ...

  10. sql server 游标和with as使用

    ) --声明变量,需要读取的数据 DECLARE cur CURSOR --去掉STATIC关键字即可 FOR WITH Emp AS (SELECT acc.* FROM GXSpreadDB.db ...