这题看数据范围,如果一个一个存入,那一定会爆掉的,所以要用优先队列来存,然后要合并的来操作,不要真的取一个一个的加,把小的先合并起来,然后放进去,如果是奇数个就把一个放回去,其他全部加到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;
}