Problem 2277 Change
Accept: 38 Submit: 241
Time Limit: 2000 mSec Memory Limit : 262144 KB
Problem Description
There is a rooted tree with n nodes, number from 1-n. Root’s number is 1.Each node has a value ai.
Initially all the node’s value is 0.
We have q operations. There are two kinds of operations.
1 v x k : a[v]+=x , a[v’]+=x-k (v’ is child of v) , a[v’’]+=x-2*k (v’’ is child of v’) and so on.
2 v : Output a[v] mod 1000000007(10^9 + 7).
Input
First line contains an integer T (1 ≤ T ≤ 3), represents there are T test cases.
In each test case:
The first line contains a number n.
The second line contains n-1 number, p2,p3,…,pn . pi is the father of i.
The third line contains a number q.
Next q lines, each line contains an operation. (“1 v x k” or “2 v”)
1 ≤ n ≤ 3*10^5
1 ≤ pi < i
1 ≤ q ≤ 3*10^5
1 ≤ v ≤ n; 0 ≤ x < 10^9 + 7; 0 ≤ k < 10^9 + 7
Output
For each operation 2, outputs the answer.
Sample Input
1
3
1 1
3
1 1 2 1
2 1
2 2
Sample Output
2
1
題意:給你一個n個節點n-1條邊的樹,1爲樹根。q次操作
1: v x k : a[v]+=x , a[v’]+=x-k (v’ is child of v) , a[v’’]+=x-2*k (v’’ is child of v’) and so on.應該能看懂吧,描述起來有點難。
2:詢問v點的val。
題解:對於1操作來說,假設v是這個點,設x爲v的所有子節點,則
val[x]+=x-k*(dep[x]-dep[v])等價於val[x]+=x+k*dep[v]-k*dep[x];
則我們可以用兩個樹狀數組分別維護x+k*dep[v]和k。樹狀數組應支持區間修改,單點查詢。最後注意下負數取模的問題。
代碼:
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<vector>
#include<queue>
#include<algorithm>
#include<map>
#define NI freopen("in.txt","r",stdin);
#define NO freopen("out.txt","w",stdout);
using namespace std;
typedef long long int ll;
typedef pair<int,int>pa;
const int N=1e6+10;
const ll mod=1e9+7;
const ll INF=1e18;
int read()
{
int x=0;
char ch = getchar();
while('0'>ch||ch>'9')ch=getchar();
while('0'<=ch&&ch<='9')
{
x=(x<<3)+(x<<1)+ch-'0';
ch=getchar();
}
return x;
}
/************************************************************/
struct node
{
int to,next;
} edge[N<<2];
int n,p,cnt,id,t,x,op,v;
ll xx,k;
ll qx[N][2];
int st[N],ed[N],q[N],dep[N];
int head[N<<2];
int lowbit(int x)
{
return x&(-x);
}
void update(int x,ll vl,int op)
{
for(;x&&x<=n;x+=lowbit(x))
{
qx[x][op]+=vl;
qx[x][op]=qx[x][op]%mod;
}
}
ll query(int x,int op)
{
ll res=0;
for(;x;x-=lowbit(x))
{
res+=qx[x][op];
res=res%mod;
}
return res%mod;
}
void init()
{
cnt=0;
id=0;
memset(head,-1,sizeof(head));
memset(qx,0,sizeof(qx));
}
void add(int u,int v)
{
edge[cnt].to=v;
edge[cnt].next=head[u];
head[u]=cnt++;
}
void redfs(int u,int fa,int d)
{
st[u]=++id;
q[id]=u;
dep[u]=d;
for(int i=head[u]; i!=-1; i=edge[i].next)
{
int v=edge[i].to;
if(v!=fa)
{
redfs(v,u,d+1);
}
}
ed[u]=id;
}
void solve(int v,ll x,ll k)
{
int l=st[v];
int r=ed[v];
update(l,x+k*(ll)dep[v],0);
update(r+1,-x-k*(ll)dep[v],0);
update(l,k,1);
update(r+1,-k,1);
}
int main()
{
scanf("%d",&t);
while(t--)
{
init();
scanf("%d",&n);
for(int i=2;i<=n;i++)
{
scanf("%d",&x);
add(i,x);
add(x,i);
}
redfs(1,0,1);
scanf("%d",&p);
while(p--)
{
scanf("%d",&op);
if(op==1)
{
scanf("%d%I64d%I64d",&v,&xx,&k);
solve(v,xx,k);
}
else
{
scanf("%d",&v);
ll ans=query(st[v],0)%mod-(query(st[v],1)%mod)*((ll)dep[v]%mod)%mod;
ans = (ans%mod+mod)%mod;
printf("%I64d\n",ans%mod);
}
}
}
return 0;
}