您的位置:首页 > 编程语言

2014年编程之美初赛第一场-树

2014-04-19 23:22 453 查看

题目2 : 树

时间限制:4000ms单点时限:2000ms内存限制:256MB

描述

有一个N个节点的树,其中点1是根。初始点权值都是0。一个节点的深度定义为其父节点的深度+1,。特别的,根节点的深度定义为1。现在需要支持一系列以下操作:给节点u的子树中,深度在l和r之间的节点的权值(这里的深度依然从整个树的根节点开始计算),都加上一个数delta。问完成所有操作后,各节点的权值是多少。为了减少巨大输出带来的开销,假设完成所有操作后,各节点的权值是answer[1..N],请你按照如下方式计算出一个Hash值(请选择合适的数据类型,注意避免溢出的情况)。最终只需要输出这个Hash值即可。MOD =1000000007; // 10^9 + 7MAGIC= 12347;Hash =0;For i= 1 to N do   Hash = (Hash * MAGIC + answer[i]) mod MOD;EndFor

输入

第一行一个整数T (1 ≤ T ≤ 5),表示数据组数。接下来是T组输入数据,测试数据之间没有空行。每组数据格式如下:第一行一个整数N (1 ≤ N ≤ 105),表示树的节点总数。接下来N - 1行,每行1个数,a (1 ≤ a ≤ N),依次表示2..N节点的父亲节点的编号。接下来一个整数Q(1 ≤ Q ≤ 105),表示操作总数。接下来Q行,每行4个整数,u, l, r, delta (1 ≤ u ≤ N, 1 ≤ l ≤ r ≤ N, -109 ≤ delta ≤ 109),代表一次操作。

输出

对每组数据,先输出一行“Case x: ”,x表示是第几组数据,然后接这组数据答案的Hash值。

数据范围

小数据:1 ≤ N, Q ≤ 1000大数据:1 ≤ N, Q ≤ 105

样例解释

点1的子树中有1,2,3三个节点。其中深度在2-3之间的是点2和点3。点2的子树中有2,3两个节点。其中没有深度为1的节点。所以,执行完所有操作之后,只有2,3两点的权值增加了1。即答案是0 1 1。再计算对应的Hash值即可。样例输入
1
3
1
2
2
1 2 3 1
2 1 1 1
样例输出
Case 1: 12348
参考别人的代码。。。
#include <iostream>
#include <vector>
using namespace std;

vector<int> children(int node, int* father, int n)
{
vector<int> res;
for (int i = 0; i < n; ++i){
if (father[i] == node){
res.push_back(i);
vector<int> cs = children(i, father, n);
if (cs.size() != 0){
for (int j = 0; j < cs.size(); ++j){
res.push_back(cs[j]);
}
}
}
}

return res;
}
int main()
{
int T;
cin >> T;
for (int c = 0; c < T; ++c){
int N;
cin >> N;
int* w = new int
;
for (int i = 0; i < N; ++i){
w[i] = 0;
}
int* father = new int
;
for (int i = 1; i < N; ++i){
cin >> father[i];
father[i]--;
}
// build the tree
int* dep = new int
;
dep[0] = 1;
for (int i = 1; i < N; ++i)
{
int d = 1;
int node = i;
while (node != 0)
{
node = father[node];
++d;
}
dep[i] = d;
}
int Q;
cin >> Q;
for (int i = 0; i < Q; ++i)
{
int u, l, r, delta;
cin >> u >> l >> r >> delta;
//do the operation
vector<int> childs = children(u-1, father, N);

for (int j = 0; j < childs.size(); ++j)
{
if (dep[childs[j]] >= l && dep[childs[j]] <= r)
{
w[childs[j]] += delta;
}
}
}
//calc hash
int MOD = 1000000007;
int MAGIC = 12347;
int Hash = 0;
for (int i = 0; i < N; ++i)
{
Hash = (Hash*MAGIC + w[i]) % MOD;
}
//output
cout << "Case " << c+1 << ": " << Hash << endl;
}
return 0;
}

                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  编程之美