第4场H。

智乃的果子

https://ac.nowcoder.com/acm/contest/120565/D

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

相关推荐

01-22 14:36
门头沟学院 Java
不知道怎么取名字_:我就好奇,你是这家的hr还是?咋这都能搞到
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务