有一个N个节点的树,其中点1是根。初始点权值都是0。
一个节点的深度定义为其父节点的深度+1,。特别的,根节点的深度定义为1。
现在需要支持一系列以下操作:给节点u的子树中,深度在l和r之间的节点的权值(这里的深度依然从整个树的根节点开始计算),都加上一个数delta。
问完成所有操作后,各节点的权值是多少。
为了减少巨大输出带来的开销,假设完成所有操作后,各节点的权值是answer[1..N],请你按照如下方式计算出一个Hash值(请选择合适的数据类型,注意避免溢出的情况)。最终只需要输出这个Hash值即可。
```c++
MOD =1000000007; // 10^9 + 7
MAGIC= 12347;
Hash =0;
For i= 1 to N do
Hash = (Hash * MAGIC + answer[i]) mod MOD;
EndFor
````
第一行一个整数N ,表示树的节点总数。
接下来N - 1行,每行1个数,a (1 ≤ a ≤ N),依次表示2..N节点的父亲节点的编号。
接下来一个整数Q,表示操作总数。
接下来Q行,每行4个整数,u, l, r, delta (1 ≤ u ≤ N, 1 ≤ l ≤ r ≤ N, -10^9 ≤ delta ≤ 10^9),代表一次操作。
### 输入
```plain
3
1
2
2
1 2 3 1
2 1 1 1
```
### 输出
```
12348
```
#include<iostream> #include<cstdio> #include<vector> #include<algorithm> #define ll long long using namespace std; const int N = 1e6+5; int read(){ int f = 1, x = 0; char c = getchar(); while(c < '0' || c >'9'){ if(c == '-') f = -1; c = getchar(); } while(c >= '0' && c <= '9'){ x = (x<<1) + (x<<3) + (c - '0'); c = getchar(); } return x*f; } int n, cnt, m, hd[N], l[N], r[N], d[N]; ll ans[N], c[N]; vector<int> q[N]; struct Node{ int to,nxt; }edge[N]; void add(int u, int v){ edge[++cnt].to = v; edge[cnt].nxt = hd[u]; hd[u] = cnt; } void dfs(int u, int dep, ll sum) { //自上而下 for(int i = 0; i < q[u].size(); i++) { int j = q[u][i]; //第几个询问 if(r[j] < dep) continue; c[max(dep, l[j])] += d[j]; //c表示层数,这层执行差分 c[r[j] + 1] -= d[j]; } ans[u] = sum + c[dep]; //前缀和 for(int i = hd[u]; i; i = edge[i].nxt) dfs(edge[i].to, dep+1, sum+c[dep]);//如果没有增加,则c[dep]=0 for(int i = 0; i < q[u].size(); i++){ int j = q[u][i]; //第几个询问 if(r[j] < dep) continue; c[max(dep, l[j])] -= d[j]; c[r[j] + 1] += d[j]; } } int main() { scanf("%d",&n); int x; ll p = 0; for(int i = 2; i <= n; i++) { // scanf("%d",&x); x = read(); add(x,i);//单向边 } scanf("%d",&m); for(int i = 1; i <= m; i++) { x = read(); l[i] = read(); r[i] = read(); d[i] = read(); q[x].push_back(i); //这个子树对应的第几个询问 } dfs(1,1,0); for(int i = 1; i <= n; i++) p = (p * 12347 + ans[i]) % 1000000007; printf("%lld\n",p); return 0; }