可以证明得到性质:
1:每次选取最小的两个数,最后得到的数是最大的
如果直接这么暴力做,先排序,每次删去两个数得到一个数,将得到的新数插入排好序的数中。显然会超时间,long long也不够用。
2. 前一次得到的数,一定比这一次得到的数小,满足单调性。
由性质二,当得到的数第一次大于原数列中最大的数时,后面的数都会大于原序列最大的数,因此插入是在原数列后面依次插入。满足单调,有序性。因此将堆中的所有数取出加入队列操作。
#include <iostream>
#include <cstring>
#include <queue>
using namespace std;
typedef long long LL;
const int MOD = 1e9 + 7;
int main()
{
int x, maxn;
int n, k;
cin >> n >> k;
priority_queue<int, vector<int>, greater<int> > heap;
queue<int> q;
for (int i = 0; i < n; i ++) {cin >> x; heap.push(x); maxn = max(x, maxn);};
while (heap.size() > 1)
{
int x1 = heap.top(); heap.pop();
int x2 = heap.top(); heap.pop();
LL x3 = (LL)x1 * x2 + k;
if (x3 > maxn)
{
heap.push(x1); heap.push(x2);
break;
}
else
heap.push(int(x3));
}
while (heap.size())
{
q.push(heap.top());
heap.pop();
}
while (q.size() > 1)
{
int x1 = q.front();
q.pop();
int x2 = q.front();
q.pop();
int x3 = ((LL)x1 * x2 + k) % MOD;
q.push(x3);
}
cout << q.front();
}