题目链接:https://ac.nowcoder.com/acm/problem/212913

到主站看:https://blog.csdn.net/weixin_43346722/article/details/109226431

题目

公司中总共有 个人,其中第 个人的初始工资为 。公司根据每个人的绩效(工作表现)来评定每个人的涨薪幅度。每年有 个人绩效为 A,工资可以变为原来的 倍; 个人绩效为 B,工资可以变为原来的 倍,其余人绩效为 C,工资不变,连续两年绩效为 C 会被开除。(保证 )

假如公司没有一直招聘新员工,请问 年后,公司需要给所有在职员工支付的工资总和最多为多少。由于答案可能很大,请输出对 取模后的结果。

输入

输入第一行包含四个正整数 ,意义如题面所示。
接下来一行包含 个正整数,第 个正整数为 代表第 个人的初始工资。

输出

输出一行一个整数表示 年后工资总和对 取模后的结果。

样例输入1

2 1 1 1
5 3

样例输出1

21

样例输入2

2 2 0 0
5 2

样例输出2

0

数据范围

对于 的数据范围,满足
对于 的数据范围,满足
对于另外 的数据范围,满足 满足
对于另外 的数据范围,满足 满足
对于 的数据范围,满足

思路

这道题是一道贪心。

我们可以发现,我们一直把 A 给初始值最大的那些人,把 B 给初始值接着大的人是最优的。
至于别的人,被开除也无所谓(好惨

求 A 类人和 B 类人的贡献就先用快速幂求出每类人增长的倍数,然后乘上去即可。

有一个细节,就是如果年数小于 年的话 C 类人不会被开除,就还要算上它们的。

比赛时

看出来了,就码出来了。
图片说明

代码

#include<cstdio>
#include<iostream>
#include<algorithm>
#define ll long long
#define mo 1000000007

using namespace std;

ll n, m, x, y, a[100001], Asum, Bsum, Esum, mi3, mi2, re, ***;
char c;

ll read() {
    re = 0;
    *** = 1;
    c = getchar();
    while ((c < '0' || c > '9') && c != '-') c = getchar();
    if (c == '-') {
        *** = -1;
        c = getchar();
    }
    while (c >= '0' && c <= '9') {
        re = re * 10 + c - '0';
        c = getchar();
    }
    return re * ***;
}

bool cmp(ll x, ll y) {
    return x > y;
}

ll ksm(ll x, ll y) {//快速幂
    re = 1;
    while (y) {
        if (y & 1) re = (re * x) % mo;
        x = (x * x) % mo;
        y >>= 1;
    }
    return re;
}

int main() {
    n = read();
    m = read();
    x = read();
    y = read();
    for (ll i = 1; i <= n; i++) a[i] = read();

    mi3 = ksm(3, m);//预处理出翻的倍数
    mi2 = ksm(2, m);

    sort(a + 1, a + n + 1, cmp);//从大到小排序

    for (ll i = 1; i <= x; i++)//最前面的(最大的)绩效为 A
        Asum = (Asum + (a[i] * mi3) % mo) % mo;
    for (ll i = x + 1; i <= x + y; i++)//接着(接着大的)就是绩效为 B
        Bsum = (Bsum + (a[i] * mi2) % mo) % mo;
    if (m < 2)//只有年数小于两年,这些 C 的才不会被开除,才要记录
        for (ll i = x + y + 1; i <= n; i++)
            Esum = (Esum + (a[i] * m) % mo) % mo;

    printf("%lld", (Asum + Bsum + Esum) % mo);

    return 0;
}