Codeforces I. Producing Snow(优先队列)
题目描述:
C. Producing Snow
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output
Alice likes snow a lot! Unfortunately, this year’s winter is already over, and she can’t expect to have any more of it. Bob has thus bought her a gift — a large snow maker. He plans to make some amount of snow every day. On day i he will make a pile of snow of volume Vi and put it in her garden.
Each day, every pile will shrink a little due to melting. More precisely, when the temperature on a given day is Ti, each pile will reduce its volume by Ti. If this would reduce the volume of a pile to or below zero, it disappears forever. All snow piles are independent of each other.
Note that the pile made on day i already loses part of its volume on the same day. In an extreme case, this may mean that there are no piles left at the end of a particular day.
You are given the initial pile sizes and the temperature on each day. Determine the total volume of snow melted on each day.
Input
The first line contains a single integer N (1 ≤ N ≤ 105) — the number of days.
The second line contains N integers V1, V2, …, VN (0 ≤ Vi ≤ 109), where Vi is the initial size of a snow pile made on the day i.
The third line contains N integers T1, T2, …, TN (0 ≤ Ti ≤ 109), where Ti is the temperature on the day i.
Output
Output a single line with N integers, where the i-th integer represents the total volume of snow melted on day i.
Examples
Input
Copy
3
10 10 5
5 7 2
Output
5 12 4
Input
Copy
5
30 25 20 15 10
9 10 12 4 13
Output
9 20 35 11 25
Note
In the first sample, Bob first makes a snow pile of volume 10, which melts to the size of 5 on the same day. On the second day, he makes another pile of size 10. Since it is a bit warmer than the day before, the first pile disappears completely while the second pile shrinks to 3. At the end of the second day, he has only a single pile of size 3. On the third day he makes a smaller pile than usual, but as the temperature dropped too, both piles survive till the end of the day.
思路:
题目是说,每天造出一堆雪,同时所有堆雪每天融化一点,如果融完了这堆雪就没了,求每一天的所有堆雪的融雪量。刚开始,模拟嘛,就见一个链表,每个节点模拟一堆雪,融完就删节点,比数组标记起来会快一点。每次从头统计一下融雪量。但是这样做太too young too simple了,数据量稍大一点就会超时。因为每次都要遍历一遍链表,最坏的情况是没有雪融完,链表越来越长,要遍历\(1+2+3+...+10^5\approx10^{10}\),不潮湿?超时!而且我还中间因为链表指针没搞清楚,在删除链表末的节点时漏了处理一个指向链表尾的重要指针,一直莫名错误,改了好久,放个代码。
#include <cstdio>
#define max_n 100005
using namespace std;
int N;
int V[max_n];
int T[max_n];
struct Node
{
Node* nxt;
int vol;
};
Node* head;
Node* p;
inline void read(int& x)
{
x=0;
int f=0;
char ch=getchar();
while('0'>ch||ch>'9')
{
if(ch=='-')
f=1;
ch=getchar();
}
while('0'<=ch&&ch<='9')
{
x=10*x+ch-'0';
ch=getchar();
}
x=f?-x:x;
}
inline Node* del(Node* fro,Node* ite)
{
Node* nxt = ite->nxt;
/*cout << "vol" << ite->vol << endl;
if(nxt==NULL)
{
printf("Yes\n");
}*/
if(nxt==NULL)
{
p = fro;
}
fro->nxt = nxt;
ite->nxt = NULL;
delete ite;
ite = nxt;
return ite;
//cout << "ite->nxt " << ite->vol << endl;
}
#pragma optimize(2)
int main()
{
head = new Node;
head->nxt = NULL;
p = head;
read(N);
for(int i = 0; i<N; i++)
{
read(V[i]);
}
for(int j = 0; j<N; j++)
{
read(T[j]);
}
for(int i = 0; i<N; i++)
{
Node* node = new Node;
node->vol = V[i];
node->nxt = NULL;
p->nxt = node;
p = node;
long long reduce = 0;
Node* ite = head->nxt;
Node* fro = head;
while(ite!=NULL)
{
//cout << "T " << T[i] << endl;
//cout << "ite " << ite->vol << endl;
if(ite->vol<=T[i])
{
reduce =(long long) reduce + ite->vol;
ite = del(fro,ite);
//cout << "ite nxt " << ite->vol << endl;
}
else
{
reduce = (long long) reduce + T[i];
ite->vol -= T[i];
fro = ite;
ite = ite->nxt;
}
}
printf("%I64d ",reduce);
}
return 0;
}
然后就想什么限时一秒肯定有简便(正确)做法,想到了二分查找雪堆最弱(最容易消掉)的那一个,但好像排序的话会毁掉时间,而且因为生产的时间不同,每堆雪的抗融能力不能仅仅通过雪堆大小衡量。又想能不能预处理一下数组然后可以直接得出结果。怎么预处理?误打误撞想到了前缀和。因为每堆雪的消亡只与它和之后的时间有关,那岂不是要对于每一堆雪计算一个前缀和,然后陷入了思索。
其实我是没想出正解的,因为看了题解也没看懂。。现在好像有点懂了。思路大概是这样:先计算出每天消雪量的前缀和,使用优先队列(从小到大),然后每次把这一天的雪堆与前一天的消雪前缀和之和(思考一下为什么是这样的?)加入队列。每次比较一下队列最小值跟当前消雪量前缀和。这个比较有什么意义?首先要明白当前消雪量前缀和有什么意义,它表示包括今天之前的所有天本应该消去的雪量。当前队列最小值表示到今天为止最多能承受的消雪量,为什么?因为队列最小值是某天的雪量加上那天之前的雪量前缀和。最小值小于当前前缀和就说明从那个某天开始生产出来的那堆雪到了今天已经要消完了。于是把这些堆的雪消完,统计总共的消雪量。队列里留下的就是还没消完的雪堆能承受的最大消雪量,给他们也统计下今天应该消掉的雪,加到前面的统计量里,就得到了今天的实际消雪量。到了以后某天就可能会发现今天生产的雪在那天承受不住了,也要消完了,就会在那天消完今天的雪,排出队列。
代码:
#include <iostream>
#include <queue>
#define max_n 100005
using namespace std;
int N;
int V[max_n];
int T[max_n];
long long sum[max_n];
priority_queue<long long,vector<long long>,greater<long long> > que;
int main()
{
cin >> N;
for(int i = 1;i<=N;i++)
{
cin >> V[i];
}
for(int i = 1;i<=N;i++)
{
long long ans = 0;
cin >> T[i];
sum[i] = sum[i-1]+T[i];
que.push(sum[i-1]+V[i]);
while(!que.empty()&&que.top()<=sum[i])
{
ans += que.top()-sum[i-1];
que.pop();
}
//cout << "sum[i]-sum[i-1] " << sum[i]-sum[i-1] << endl;
ans += (sum[i]-sum[i-1])*que.size();
cout << ans << " ";
}
return 0;
}
参考文章:
HOrchard,Codeforces 923B Producing Snow(优先队列),https://blog.csdn.net/HOrchard/article/details/79594634
Codeforces I. Producing Snow(优先队列)的更多相关文章
- Codeforces 948C Producing Snow(优先队列+思维)
题目链接:http://codeforces.com/contest/948/problem/C 题目大意:给定长度n(n<=1e5),第一行v[i]表示表示第i堆雪的体积,第二行t[i]表示第 ...
- CodeForces - 948C Producing Snow(优先队列)
题意: n天. 每天你会堆一堆雪,体积为 v[i].每天都有一个温度 t[i] 所有之前堆过的雪在第 i 天体积都会减少 t[i] . 输出每天融化了的雪的体积. 这个题的正解我怎么想都很难理解,但是 ...
- 2018.12.05 codeforces 948C. Producing Snow(堆)
传送门 维护一个堆. 每次先算出一个都不弹掉的总贡献. 然后把要弹掉的弹掉,并减去它们对应的贡献. 代码: #include<bits/stdc++.h> #define ri regis ...
- 【二分】Producing Snow @Codeforces Round #470 Div.2 C
time limit per test: 1 second memory limit per test: 256 megabytes Alice likes snow a lot! Unfortuna ...
- Codeforces Round #470 (rated, Div. 2, based on VK Cup 2018 Round 1) C.Producing Snow
题目链接 题意 每天有体积为Vi的一堆雪,所有存在的雪每天都会融化Ti体积,求出每天具体融化的雪的体积数. 分析 对于第i天的雪堆,不妨假设其从一开始就存在,那么它的初始体积就为V[i]+T[1. ...
- Codeforces 923 B. Producing Snow
http://codeforces.com/contest/923/problem/B 题意: 有n天,每天产生一堆体积为Vi的雪,每天所有雪堆体积减少Ti 当某一堆剩余体积vi<=Ti时,体积 ...
- [CodeForces948C]Producing Snow(优先队列)
Description 题目链接 Solution 将温度做一个前缀和,用一个优先队列依次处理一遍 思路还是很简单的 Code #include <cstdio> #include < ...
- Codeforces 681C. Heap Operations 优先队列
C. Heap Operations time limit per test:1 second memory limit per test:256 megabytes input:standard i ...
- Codeforces Gym 101291C【优先队列】
<题目链接> 题目大意: 就是一道纯模拟题,具体模拟过程见代码. 解题分析:要掌握不同优先级的优先队列的设置.下面是对优先队列的使用操作详解: priority_queue<int& ...
随机推荐
- Csp-s2019 划分
本题主要靠结论 12pt 爆搜 时间复杂度\(O(n^n)\) 36pt \(f_{i,j}表示前i个数由状态j转移过来,a_i表示前缀和\) \(So,f_{i,j}=f_{j,k}+(a_i-a_ ...
- intellij JUnit mockito
在intellij越来越普及的情况下,利用JUnit在intellij中进行测试就显得很基础了,但网上的资料总有误导的地方,这里记录一下. 总体而言,要开始单元测试,可以分为三步,添加相关的插件,添加 ...
- Apache Kafka使用默认配置执行一些负载测试来完成性能测试和基准测试
Kafka是一种分布式,分区,复制的提交日志服务.它提供了消息传递系统的功能. 我们先来看看它的消息传递术语: Kafka在称为主题的类别中维护消息的提要. 我们将调用向Kafka主题生成器发布消 ...
- C语言输入带空格的字符串
参考:https://blog.csdn.net/vincemar/article/details/78750435 因为: scanf("%s",str); 遇到空格就停止接收后 ...
- Java学习:迭代器简介
迭代器 java.util.Iterator接口:迭代器(对集合进行遍历) 有两个常用的方法 boolean hasNext() 如果仍有元素可以迭代,则返回 true. 判断集合中还有没有下一个元素 ...
- GoF的23种设计模式之创建型模式的特点和分类
创建型模式的主要关注点是“怎样创建对象?”,它的主要特点是“将对象的创建与使用分离”.这样可以降低系统的耦合度,使用者不需要关注对象的创建细节,对象的创建由相关的工厂来完成.就像我们去商场购买商品时, ...
- Remote System Explorer Operation总是运行后台服务,卡死eclipse解决办法
当你右键编辑控件的id或者其他属性时都会卡很久,发现原来是eclipse后台进程在远程操作,就是右下角显示的“Remote System Explorer Operation”.折腾了半天,在Stac ...
- 阿里 P8 高级架构师吐血总结的 《Java 核心知识整理&面试.pdf》| 免费分享
最近在网上发现一份非常棒的 PDF 资料,据说是阿里 P8 级高级架构师吐血总结的, 其中内容覆盖很广,包括 Java 核心基础.Java 多线程.高并发.Spring.微服务.Netty 与 RPC ...
- OpenStack 中 RabbitMQ 的使用
OpenStack 中 RabbitMQ 的使用 本文是 OpenStack 中的 RabbitMQ 使用研究 两部分中的第一部分,将介绍 RabbitMQ 的基本概念,即 RabbitMQ 是什么. ...
- 配置两个不同kerberos认证中心的集群间的互信
两个Hadoop集群开启Kerberos验证后,集群间不能够相互访问,需要实现Kerberos之间的互信,使用Hadoop集群A的客户端访问Hadoop集群B的服务(实质上是使用Kerberos Re ...