LCP 5. 发 LeetCoin

这是一道力扣的竞赛题目,原题目链接如下:
https://leetcode-cn.com/problems/coin-bonus/

力扣决定给一个刷题团队发LeetCoin作为奖励。同时,为了监控给大家发了多少LeetCoin,力扣有时候也会进行查询。

该刷题团队的管理模式可以用一棵树表示:

团队只有一个负责人,编号为1。除了该负责人外,每个人有且仅有一个领导(负责人没有领导);
不存在循环管理的情况,如A管理B,B管理C,C管理A。

力扣想进行的操作有以下三种:

给团队的一个成员(也可以是负责人)发一定数量的LeetCoin;
给团队的一个成员(也可以是负责人),以及他/她管理的所有人(即他/她的下属、他/她下属的下属,……),发一定数量的LeetCoin;
查询某一个成员(也可以是负责人),以及他/她管理的所有人被发到的LeetCoin之和。

输入:

N表示团队成员的个数(编号为1~N,负责人为1);
leadership是大小为(N - 1) * 2的二维数组,其中每个元素[a, b]代表b是a的下属;
operations是一个长度为Q的二维数组,代表以时间排序的操作,格式如下:
operations[i][0] = 1: 代表第一种操作,operations[i][1]代表成员的编号,operations[i][2]代表LeetCoin的数量;
operations[i][0] = 2: 代表第二种操作,operations[i][1]代表成员的编号,operations[i][2]代表LeetCoin的数量;
operations[i][0] = 3: 代表第三种操作,operations[i][1]代表成员的编号;
输出:

返回一个数组,数组里是每次查询的返回值(发LeetCoin的操作不需要任何返回值)。由于发的LeetCoin很多,请把每次查询的结果模1e9+7 (1000000007)。

代码如下:

class Bonus {

    public int[] bonus(int n, int[][] leadership, int[][] operations) {
        ArrayList<Integer> res = new ArrayList<>();
        BonusNode[] a = new BonusNode[n + 1];
        for (int i = 0; i <= n; i++)
            a[i] = new BonusNode();
        for (int i = 0; i < leadership.length; i++) {
            int p = leadership[i][0];
            int son = leadership[i][1];
            a[son].parent = a[p];
            a[p].teamSize++;
        }
        for (int i = 0; i < operations.length; i++) {
            if (operations[i][0] == 1) {
                BonusNode node = a[operations[i][1]];
                node.self = (node.self + operations[i][2]) % 1000000007;
                node = node.parent;
                while (node != null) {
                    node.self = (node.self + operations[i][2]) % 1000000007;
                    node = node.parent;
                }
            } else if (operations[i][0] == 2) {
                BonusNode node = a[operations[i][1]];
                node.common = (node.common + operations[i][2]) % 1000000007;
                int count = node.teamSize;
                node = node.parent;
                while (node != null) {
                    int t = (operations[i][2] * count) % 1000000007;
                    node.self = (node.self + t) % 1000000007;
                    node = node.parent;
                }
            } else if (operations[i][0] == 3) {
                res.add(GetCount(a[operations[i][1]]));
            }
        }
        int[] resArr = new int[res.size()];
        for (int i = 0; i < res.size(); i++)
            resArr[i] = res.get(i);
        return resArr;
    }

    private int GetCount(BonusNode node) {
        long temp = 0;
        temp = (temp + node.self) % 1000000007;
        int teamSize = node.teamSize;
        while(node != null){
            long t = (node.common * teamSize) % 1000000007;
            temp = (temp + t)  % 1000000007;
            node = node.parent;
        }
        return (int)temp;
    }

}

class BonusNode {
    int teamSize = 1;
    BonusNode parent = null;
    long self = 0;
    long common = 0;
    public BonusNode(){
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值