涨薪(快速幂)

题目描述
公司中总共有n个人,其中第i个人的初始工资为ai。公司根据每个人的绩效(工作表现)来评定每个人的涨薪幅度。每年有x个人绩效为A,工资可以变为原来的3倍;y个人绩效为B,工资可以变为原来的2倍,其余人绩效为C,
工资不变,连续两年绩效为C会被开除。(保证x+y≤n)
假如公司没有一直招聘新员工,请问m年后,公司需要给所有在职员工支付的工资总和最多为多少。由于答案可能很大,请输出对109+7取模后的结果。

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

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

样例输入
【样例1】
2 1 1 1
5 3
【样例2】
2 2 0 0
5 2

样例输出
【样例1】
21
【样例2】
0

提示
对于20%的数据范围,满足n≤10,m≤10,ai≤10
对于40%的数据范围,满足n≤105,m≤10,ai≤105
对于另外20%的数据范围,满足n≤105,m≤10,ai≤105且x+y=n
对于另外20%的数据范围,满足n≤105,m≤109,ai≤105且x+y=n
对于100%的数据范围,满足1≤n≤105,1≤m≤109,1≤ai≤105

思路:

要想支付的钱最多,那么给绩效A和绩效B工资最高的人涨薪即可

注意:绩效为C的人不要忘了计算,快速幂运算的时候记得取模的位置,赋值语句不能写ans_tmp *= a%p 要写成ans_tmp = ans_tmp * a %p

AC代码

#include <iostream>
#include <vector>
#include <algorithm>
 
using namespace std;
 
typedef long long ll;
 
ll n,m,x,y,ans,tmp,aa,bb;
ll p = 1e9+7;
vector<ll> a;
 
ll fastpow(ll a,int n)
{
    ll ans_tmp = 1;
    while(n)
    {
        if(n&1)
        {
            ans_tmp = ans_tmp*a%p;
        }
        a = a*a%p;
        n>>=1;
    }
    return ans_tmp;
}
 
int main()
{
    ios::sync_with_stdio(false);
    cin >> n >> m >> x >> y;
    for(ll i = 1; i <= n; i++)
    {
        ll w;
        cin >> w;
        a.push_back(w);
    }
    sort(a.begin(),a.end());
    aa = fastpow(3,m);
    bb = fastpow(2,m);
    for(int i = a.size()-x; i <= a.size()-1; i++)
    {
        ans = (ans+aa*a[i])%p;
    }
    for(int i = a.size()-x-y; i < a.size()-x; i++)
    {
        ans = (ans+bb*a[i])%p;
    }
    for(int i = 0; i < a.size()-x-y; i++)
    {
        tmp += a[i];
    }
    if(m >= 2)
    {
        cout << ans << endl;
    }
    else
    {
        cout << ans%p+tmp%p << endl;
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值