1. 程式人生 > >BUPT Summer Training #7 for Grade 14 題解

BUPT Summer Training #7 for Grade 14 題解

#include <iostream>
#include <cstdio>
#include <stack>
#include <cstring>
#include <queue>
#include <algorithm>
#include <cmath>
//#include <unordered_map>
#define N 500010
//#define lson x<<1
//#define rson x<<1|1
//#define mid ((lt[x].l+lt[x].r)/2)
//#define ID(x, y) ((x)*m+(y))
//#define CHECK(x, y) ((x)>=0 && (x)<n && (y)>=0 && (y)<m)
using namespace std;
typedef pair<long long,long long> PII;
const long long INF=0x3f3f3f3f;
const long long mod = 1e9+7;
void Open()
{
    #ifndef ONLINE_JUDGE
        freopen("D:/in.txt","r",stdin);
        //freopen("D:/my.txt","w",stdout);
    #endif // ONLINE_JUDGE
}
long long n, m, Tn;
long long c1[N], c2[N], dep[N], st[N], ed[N];
vector<long long> G[N];
void add(long long c[], long long x, long long val)
{
    for(long long i = x; i <= n+10; i += ((-i) & i)) c[i] = (c[i] + val) % mod;
}
long long getsum(long long c[], long long x)
{
    long long rnt = 0;
    for(long long i=x;i>0;i -= ((-i) & i)) rnt = (rnt + c[i])%mod;
    return rnt;
}
void dfs(long long u, long long d)
{
    dep[u] = d; st[u] = ++Tn;
    for(long long i=0;i<G[u].size();i++) dfs(G[u][i], d+1);
    ed[u] = Tn;
}
int main()
{
    Open();
    Tn = 0;
    scanf("%I64d", &n);
    for(long long i=2;i<=n;i++)
    {
        long long x;
        scanf("%I64d", &x);
        G[x].push_back(i);
    }
    dfs(1, 0);
    scanf("%I64d", &m);
    while(m--)
    {
        long long op;
        scanf("%I64d", &op);
        if(op == 1){
            long long v, x, k;
            scanf("%I64d%I64d%I64d", &v, &x, &k);
            add(c1, st[v], x + k * dep[v] % mod);
            add(c1, ed[v]+1, - (x + k * dep[v] % mod));
            add(c2, st[v], k);
            add(c2, ed[v]+1, - k);
        }else {
            long long v;
            scanf("%I64d", &v);
            long long tmp = getsum(c1, st[v]) - getsum(c2, st[v]) * dep[v];
            tmp = (tmp%mod + mod)%mod;
            printf("%I64d\n", tmp);
        }
    }
    return 0;
}