漲薪【貪心】【快速冪】

ssl_fuyang發表於2020-10-21

>Link

牛客1020普及T3


>Description
一共有n個數,第i個數的值為 a i a_i ai
可以進行m輪操作:選擇其中x個數乘3,其中y個數乘2,對於每個 a i a_i ai在每一輪不可以被選擇兩次。如果一個數連續兩輪沒被選擇,就直接淘汰
求最終剩下的數的總和最大為多少,答案模1e9+7


>解題思路
貪心+快速冪

將a陣列從大到小排個序,只選擇前x+y個數,後面的直接淘汰(m=1的情況除外),並且乘3操作永遠只選前x個數,選擇的數中剩下的就永遠都乘2


>程式碼

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define int long long
#define N 100005
using namespace std;

const int p = 1e9 + 7;
int n, m, x, y, a[N], ans, sum[N];

bool cmp (int aa, int bb) {return aa > bb;}
int power (int aa, int bb)
{
	int ret = 1;
	for (; bb; bb >>= 1, aa = aa * aa % p)
	  if (bb & 1) ret = ret * aa % p;
	return ret;
}

signed main()
{
	scanf ("%lld%lld%lld%lld", &n, &m, &x, &y);
	for (int i = 1; i <= n; i++) scanf ("%lld", &a[i]);
	sort (a + 1, a + 1 + n, cmp);
	for (int i = 1; i <= n; i++) sum[i] = (sum[i - 1] + a[i]) % p;
	ans = sum[x] * power (3, m) % p;
	ans = (ans + (sum[x + y] - sum[x]) * power (2, m) % p) % p;
	if (m == 1) ans = (ans + sum[n] - sum[x + y]) % p;
	printf ("%lld", ans);
	return 0;
}