首页 > 其他 > 详细

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

时间:2014-04-20 03:30:34      阅读:516      评论:0      收藏:0      [点我收藏+]

题目2 : 树

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

描述

有一个N个节点的树,其中点1是根。初始点权值都是0。

一个节点的深度定义为其父节点的深度+1,。特别的,根节点的深度定义为1。

现在需要支持一系列以下操作:给节点u的子树中,深度在l和r之间的节点的权值(这里的深度依然从整个树的根节点开始计算),都加上一个数delta。

问完成所有操作后,各节点的权值是多少。


为了减少巨大输出带来的开销,假设完成所有操作后,各节点的权值是answer[1..N],请你按照如下方式计算出一个Hash值(请选择合适的数据类型,注意避免溢出的情况)。最终只需要输出这个Hash值即可。


MOD =1000000007; // 10^9 + 7

MAGIC= 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[N];
        for (int i = 0; i < N; ++i){
            w[i] = 0;
        }
        int* father = new int[N];
        for (int i = 1; i < N; ++i){
            cin >> father[i];
            father[i]--;
        }
        // build the tree
        int* dep = new int[N];
        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;
}



2014年编程之美初赛第一场-树,布布扣,bubuko.com

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

原文:http://blog.csdn.net/zzucsliang/article/details/24145139

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!