这题看数据范围,如果一个一个存入,那一定会爆掉的,所以要用优先队列来存,然后要合并的来操作,不要真的取一个一个的加,把小的先合并起来,然后放进去,如果是奇数个就把一个放回去,其他全部加到ans里面,如果c1==1,那么在取下一个看看,同样要看c1的数量和奇偶性
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int p = 1e9 + 7;
int main()
{
int n;
cin >> n;
using pa = pair<ll, ll>;
priority_queue<pa, vector<pa>, greater<pa>> q;
while (n--)
{
ll c, v;
cin >> c >> v;
q.push({v, c});
}
ll ans = 0;
while (q.size())
{
auto [v1, c1] = q.top(); q.pop();
if (c1 > 1)
{
q.push({v1 * 2, c1 / 2});
(ans += v1 * (c1 >> 1 << 1)) %= p;
if (c1 & 1) q.push({v1, 1ll});
}
else if (q.size())
{
auto [v2, c2] = q.top();
q.pop();
(ans += v1 + v2) %= p;
if (c2 > 1) q.push({v2, c2 - 1});
q.push({v1 + v2, 1});
}
else break;//到最后只剩一个堆了,那直接break,其实也可以q.size()==1作为循环断条件
}
cout << ans << endl;
}

京公网安备 11010502036488号