CodeForces - 948C Producing Snow(优先队列)

题意:

n天。

每天你会堆一堆雪,体积为 v[i]。每天都有一个温度 t[i] 所有之前堆过的雪在第 i 天体积都会减少 t[i] 。

输出每天融化了的雪的体积。

这个题的正解我怎么想都很难理解,但是慢慢理解了。

计算一个 t[i] 的前缀和 sum。

那么到第 j 天时,设第 i 堆雪融化的体积是 V,则 V = min (sum [ j ] - sum[ i-1], v[ i ] )

所以把 v[ i ] + sum[ i -1] 加入优先队列里,就可以只处理所有当天能化完的雪了。

若 sum[ j ] - v [i] + sum[i - i] <= 0,则证明第 i 堆雪在第 j 天能化完,对答案贡献为V。

否则对答案贡献为 t[i] 。

#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;

#define maxn 100000 + 1000
typedef long long LL;

int main()
{
    int n;
    scanf("%d", &n);

    int v[maxn], t[maxn];
    for (int i = 1; i <= n; i++)
        scanf("%d", &v[i]);

    LL sum[maxn];
    sum[0] = 0;

    for (int i = 1; i <= n; i++)
    {
        scanf("%d", &t[i]);
        sum[i] = sum[i-1] + t[i];
    }

    priority_queue<LL, vector<LL>, greater<LL> > q;
    for (int i = 1; i <= n; i++)
    {
        q.push(v[i] + sum[i-1]);
        LL ans = 0;
        while(!q.empty())
        {
            LL x = q.top();
            if (sum[i]-x >= 0)//这堆雪第 i 天能够融化
            {
                ans += t[i] - (sum[i]-x);
                q.pop();
            }
            else break; // 否则后面的都化不完了
        }
        ans += q.size() * t[i];

        printf("%lld%c", ans, i==n? ‘\n‘:‘ ‘);
    }
}

原文地址:https://www.cnblogs.com/ruthank/p/9374017.html

时间: 2024-11-07 14:45:32

CodeForces - 948C Producing Snow(优先队列)的相关文章

Codeforces Round #470 (rated, Div. 2, based on VK Cup 2018 Round 1)C. Producing Snow+差分标记

题目链接:C. Producing Snow 题意:给两个数组v[N],T[N],v[i]表示第i天造的雪,T[i],表示第i天的温度,一堆雪如果<=T[i],当天就会融完,否则融化T[i],要求输出每天的融雪总量. 题解:我对T数组求个前缀和,就可以二分找到每堆雪在那一天(pos)融化,余下的要加进答案中ans[i],然后用一个an数组在a[i]+1,a[pos]-1,最后求再求一次前缀和. ans[i]再加上an[i]*t[i].每次操作二分logn,N次操作.复杂度O(nlogn) #in

codeforces 128 B. String 优先队列

链接:http://codeforces.com/contest/128/problem/B B. String time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output One day in the IT lesson Anna and Maria learned about the lexicographic order. Stri

Codeforces Round #470 (Div 2) B 数学 C 二分+树状数组 D 字典树

Codeforces Round #470 B. Primal Sport 数学题,对 x2 和 x1 分解质因子即可. #include<bits/stdc++.h> using namespace std; #pragma comment(linker, "/STACK:102400000,102400000") #define rep(i,a,b) for (int i=a; i<=b; ++i) #define per(i,b,a) for (int i=b;

Codeforces Round #243 (Div. 2) C. Sereja and Swaps(优先队列 暴力)

题目 题意:求任意连续序列的最大值,这个连续序列可以和其他的 值交换k次,求最大值 思路:暴力枚举所有的连续序列.没做对是因为 首先没有认真读题,没看清交换,然后,以为是dp或者贪心 用了一下贪心,各种bug不对. 这次用了一下优先队列,以前用的不多,看这个博客又学了一下 AC代码: 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cstdlib> 5 #i

Codeforces 446B DZY Loves Modification 矩阵行列分开考虑 优先队列+构造

题目链接:点击打开链接 题意: 给定n行m列的矩阵 k次操作,一个常数p ans = 0; 对于每次操作 可以任选一行或一列, 则ans += 这行(列)的数字和 然后这行(列)上的每个数字都-=p 问最大的ans 思路: 首先我们设最终选了 行 i 次,则列选了 k-i 次 那么假设我们先全部选行,然后选列,则每次选列时,要-= i*p 这样最后是 -= i*(k-i)*p 也就是所有行对列的影响 那我们先把这个 i*(k-i)*p 提出来,那么选行和选列就互不影响 就可以分别考虑行和列 对于

Codeforces Round #FF/#255 D DZY Loves Modification --贪心+优先队列

题意:给你一个矩阵,每次选某一行或者某一列,得到的价值为那一行或列的和,然后该行每个元素减去p.问连续取k次能得到的最大总价值为多少. 解法: 如果p=0,即永远不减数,那么最优肯定是取每行或每列那个最大的取k次,所以最优解由此推出. 如果不管p,先拿,最后再减去那些行列交叉点,因为每个点的值只能取一次,而交叉点的值被加了两次,所以要减掉1次,如果取行A次,取列B次,那么最后答案为: res = dp1[A] + dp2[B] - B*(k-A)*p,可以细细体会一下后面那部分. 其中: dp1

Codeforces Round #FF (Div. 2) D. DZY Loves Modification 贪心+优先队列

链接:http://codeforces.com/problemset/problem/447/D 题意:一个n*m的矩阵.能够进行k次操作,每次操作室对某一行或某一列的的数都减p,获得的得分是这一行或列原来的数字之和.求N次操作之后得到的最高得分是多少. 思路:首先分别统计每行和每列的数字和. 进行的k次操作中,有i次操作是对行进行操作,剩余k-i次操作是对列进行操作. 首先在操作中忽略每次操作中行对列的影响,然后计算列的时候,最后能够计算出,总共的影响是i*(k-i)*p. 找出对于每一个i

Codeforces 1132D - Stressful Training - [二分+贪心+优先队列]

题目链接:https://codeforces.com/contest/1132/problem/D 题意: 有 $n$ 个学生,他们的电脑有初始电量 $a[1 \sim n]$,他们的电脑每分钟会耗电 $b[1 \sim n]$,现在有一场比赛持续 $k$ 分钟. 要你买一个充电器,使得每个学生的电脑在比赛期间的任何时候的电量都不会低于 $0$(可以等于 $0$),你要求出这个充电器每分钟充电量最少是多少. 题解: 看到这种题目,应当条件反射想到二分. 假设我们现在知道充电器每分钟的充电量是

CodeForces 377B 优先队列 + 二分

题目: 呵呵,这破题目搞了我两个小时,首先题意就有点怕怕的,n个人,具有解决bug的能力,一天只能解决一个,m个bug,bug具有一个难度,只有某个人能力大于等于这个难度才可以解决,请n个人解决一个问题,每个人都要拿钞票的,问不超过s元 的情况下 最快的解决办法 输出每个bug由哪个人解决的方案 先考虑了DP,发现不行,后来就觉得是贪心了,那么就跟优先队列联系上了,把bug的难度 跟人的 解决办法能力都从大到小排,然后开始二分枚举解决天数,假设解决天数为t,那么最厉害的那个人且花费比较合适的那个