给定一棵有根的树,不一定是二叉树。该树包含N个节点,标记为1到N。将以大小为N的数组A [1..N]的形式为您提供树。A [i]表示标记为i的节点的父节点的标签。为了清楚起见,您可以假定树满足以下条件。
- The root of the tree is labeled 1. Hence A[1] is set to 0.
- The parent of node T will always have a label less than T.
任务是根据给定的查询类型执行以下操作。
- ADD,X,Y :将Y添加到节点X的值。
- ADDUP,X,Y :将Y添加到节点X的值。然后,将Y添加到A [X]的值(即X的父级)。然后,将Y添加到A [A [X]]的值(即A [X]的父级)。依此类推,直到将Y添加到根的值。
完成所有给定的操作后,将要求您回答以下几种类型的查询
- VAL,X :在节点X上打印值。
- VALTREE,X :打印以X为根(包括X)的子树中所有节点的值之和。
资料来源: Directi专访|套装13
例子:
Input:
N = 7, M = 4, Q = 5
0 1 2 2 2 1 2
ADD 6 76
ADDUP 1 49
ADD 4 48
ADDUP 2 59
VALTREE 1
VALTREE 5
VAL 5
VALTREE 2
VAL 2
Output:
291
0
0
107
59
Input:
N = 5, M = 5, Q = 3
0 1 1 1 3
ADD 1 10
ADD 2 20
ADD 3 30
ADD 4 40
ADDUP 5 50
VAL 3
VALTREE 3
VALTREE 1
Output:
80
130
250
说明:此问题是dfs的细微变化。在这种情况下,我们将节点的原始值和累加值存储在该对的向量中。我们做了2次dfs。
- dfs1用于离线查询,即计算每个节点的总和。
- dfs2将子树总和存储在数组中。
现在,所有查询都可以在固定时间内得到答复。
dfs1之前的图
dfs1之后的图
以下是所需的实现:
C++
// C++ implementation to perform
// above operations and queries
#include
using namespace std;
/*
Code Parameters
p->for every node first value is it's original value
and second value is it's addup value
subtree_sum[]-> to store the subtree_sum at every node
visit-> for dfs1
visit2->for dfs2
*/
vector > p;
vector adj[10000];
int subtree_sum[10000], visit[10000], visit2[10000];
int dfs1(int root)
{
// for leaf node
if (adj[root].size() == 0) {
// if leaf node then add the addup
// sum to it's original value
p[root].first += p[root].second;
return 0;
}
int sum = 0;
for (int i = 0; i < adj[root].size(); i++) {
if (visit[adj[root][i]] == 0) {
dfs1(adj[root][i]);
// add the addup sum of all the adjacent
// neighbors to the current node
p[root].second += p[adj[root][i]].second;
visit[adj[root][i]] = 1;
}
}
// process the root node
p[root].first += p[root].second;
return 0;
}
int dfs2(int root)
{
if (adj[root].size() == 0) {
// for the leaf node subtree_sum
// will be it's own value
subtree_sum[root] = p[root].first;
return p[root].first;
}
int sum = p[root].first;
for (int i = 0; i < adj[root].size(); i++) {
if (visit2[adj[root][i]] == 0) {
sum += dfs2(adj[root][i]);
visit2[adj[root][i]] = 1;
}
}
// calculate the subtree_sum
// for the particular root node
subtree_sum[root] = sum;
return sum;
}
// Driver code
int main()
{
int nodes = 7, m = 4, qu = 5, b;
int a[] = { 0, 1, 2, 2, 2, 1, 2 };
// for root node
p.push_back(make_pair(0, 0));
for (int i = 0; i < nodes; i++) {
if (a[i] != 0)
adj[a[i]].push_back(i + 1);
// for every node
p.push_back(make_pair(0, 0));
}
vector > > v;
v.push_back(make_pair("ADD", make_pair(6, 76)));
v.push_back(make_pair("ADDUP", make_pair(1, 49)));
v.push_back(make_pair("ADD", make_pair(4, 48)));
v.push_back(make_pair("ADDUP", make_pair(2, 59)));
for (int i = 0; i < m; i++) {
string s = v[i].first;
int a = v[i].second.first;
int b = v[i].second.second;
if (s == "ADD")
// adding to it's own value
p[a].first += b;
else
// adding to it's addup value
p[a].second += b;
}
// to process the offline queries
dfs1(1);
// to store the subtree sum for every root node
dfs2(1);
vector > q;
q.push_back(make_pair("VALTREE", 1));
q.push_back(make_pair("VALTREE", 5));
q.push_back(make_pair("VAL", 5));
q.push_back(make_pair("VALTREE", 2));
q.push_back(make_pair("VAL", 2));
for (int i = 0; i < qu; i++) {
string s = q[i].first;
int a = q[i].second;
if (s == "VAL")
cout << p[a].first << "\n";
else
cout << subtree_sum[a] << "\n";
}
}
Python3
# Python3 implementation to perform
# above operations and queries
p = []
adj = [0] * 10000
for i in range(10000):
adj[i] = []
subtree_sum, visit, visit2 = [0] * 10000, [0] * 10000, [0] * 10000
# Code Parameters
# p->for every node first value is it's original value
# and second value is it's addup value
# subtree_sum[]-> to store the subtree_sum at every node
# visit-> for dfs1
# visit2->for dfs2
def dfs1(root: int) -> int:
# for leaf node
if len(adj[root]) == 0:
# if leaf node then add the addup
# sum to it's original value
p[root][0] += p[root][1]
return 0
summ = 0
for i in range(len(adj[root])):
if visit[adj[root][i]] == 0:
dfs1(adj[root][i])
# add the addup sum of all the adjacent
# neighbors to the current node
p[root][1] += p[adj[root][i]][1]
visit[adj[root][i]] = 1
# process the root node
p[root][0] += p[root][1]
return 0
def dfs2(root: int) -> int:
if len(adj[root]) == 0:
# for the leaf node subtree_sum
# will be it's own value
subtree_sum[root] = p[root][0]
return p[root][0]
summ = p[root][0]
for i in range(len(adj[root])):
if visit2[adj[root][i]] == 0:
summ += dfs2(adj[root][i])
visit2[adj[root][i]] = 1
# calculate the subtree_sum
# for the particular root node
subtree_sum[root] = summ
return summ
# Driver Code
if __name__ == "__main__":
nodes, m, qu = 7, 4, 5
a = [0, 1, 2, 2, 2, 1, 2]
# for root node
p.append([0, 0])
for i in range(nodes):
if a[i] != 0:
adj[a[i]].append(i + 1)
# for every node
p.append([0, 0])
v = []
v.append(("ADD", [6, 76]))
v.append(("ADDUP", [1, 49]))
v.append(("ADD", [4, 48]))
v.append(("ADDUP", [2, 59]))
for i in range(m):
s = v[i][0]
a = v[i][1][0]
b = v[i][1][1]
if s == "ADD":
# adding to it's own value
p[a][0] += b
else:
# adding to it's addup value
p[a][1] += b
# to process the offline queries
dfs1(1)
# to store the subtree sum for every root node
dfs2(1)
q = []
q.append(["VALTREE", 1])
q.append(["VALTREE", 5])
q.append(["VAL", 5])
q.append(["VALTREE", 2])
q.append(["VAL", 2])
for i in range(qu):
s = q[i][0]
a = q[i][1]
if s == "VAL":
print(p[a][0])
else:
print(subtree_sum[a])
# This code is contributed by
# sanjeev2552
输出:
291
0
0
107
59