Jeanny
寂兮,寥兮,独立不改,周行而不殆

有一个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;
}

 

posted on 2023-08-12 18:51  Jeanny  阅读(33)  评论(0)    收藏  举报