【2020.10.20 牛客 普及组 模拟赛2】T3 涨薪

it2026-06-14  6

题目描述 公司中总共有 n 个人,其中第 i 个人的初始工资为 a i a_i ai 。公司根据每个人的绩效(工作表现)来评定每个人的涨薪幅度。每年有 x 个人绩效为 A,工资可以变为原来的 3 倍;y 个人绩效为 B,工资可以变为原来的 2 倍,其余人绩效为 C,工资不变,连续两年绩效为 C 会被开除。(保证 x + y ≤ n x+y≤n x+yn)

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


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

输出描述: 输出一行一个整数表示 m 年后工资总和对 1 0 9 + 7 10^9+7 109+7 取模后的结果。


示例1 输入 2 1 1 1 5 3

输出 21

示例2 输入 2 2 0 0 5 2

输出 0


备注: 对于 20 20 20% 的数据范围,满足 n ≤ 10 , m ≤ 10 , a i ≤ 10 n≤10,m≤10,a_i≤10 n10,m10,ai10

对于 40 40 40% 的数据范围,满足 n ≤ 1 0 5 , m ≤ 10 , a i ≤ 1 0 5 n≤10^5 ,m≤10,a_i≤10^5 n105,m10,ai105

对于另外 20 20 20% 的数据范围,满足 满足 n ≤ 1 0 5 , m ≤ 10 , a i ​ ≤ 1 0 5 n≤10^5 ,m≤10,a_i​ ≤10^5 n105,m10,ai105 x + y = n x+y=n x+y=n

对于另外 20 20 20% 的数据范围,满足 满足 n ≤ 105 , m ≤ 109 , a i ​ ≤ 1 0 5 n≤10 5 ,m≤10 9 ,a_i​ ≤10^5 n105,m109,ai105 x + y = n x+y=n x+y=n

对于 100 100 100% 的数据范围,满足 1 ≤ n ≤ 105 , 1 ≤ m ≤ 1 0 9 , 1 ≤ a i ​ ≤ 1 0 5 1≤n≤10 5 ,1≤m≤10^9 ,1≤a_i​≤10^5 1n105,1m109,1ai105


解题思路 贪心易得,绩效得C 的人一定是初始薪资最少的人。

其余的人进行排序,最大的x个和次大的y个分别乘3和2,其余的都不要;

因为有m天,每天都是乘同样的数,所以快速幂;


代码

#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<queue> using namespace std; const long long INF=1e9+7; long long n,m,x,y,a[110000],t,tt; long long ans1,ans2,sum; bool cmp(int x,int y) { return x>y; } long long poww(long long a ,long long b) { long long ans = 1 ; long long base = a % INF; while(b>0) { if(b&1!=0) ans = (ans*base)%INF; base=(base*base)%INF; b>>=1; } return ans; } int main() { scanf("%lld%lld%lld%lld",&n,&m,&x,&y); t=poww(2,m); tt=poww(3,m); for(int i=1; i<=n; i++) scanf("%lld",&a[i]); sort(a+1,a+n+1,cmp); for(int i=1; i<=x; i++) ans1=(ans1+a[i]*tt%INF)%INF; for(int i=x+1; i<=x+y; i++) ans2=(ans2+a[i]*t%INF)%INF; for(int i=x+y+1; i<=n; i++) sum=(sum+a[i])%INF; if(m<2) printf("%lld",((ans1+ans2)%INF+sum)%INF); else printf("%lld",((ans1+ans2)%INF)%INF); }
最新回复(0)