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& ...
随机推荐
- quick 中 "我的项目" 中的列表从那里来的?
quick 中 "我的项目" 中的列表从那里来的? 1. WelcomeScene.lua 场景 self:createOpenRecents(cc.player.settings ...
- GPS和LOAM的pose之间建立edge
基于时间戳一致原理,在与PG的timestamp邻近的的两个LOAM的pose中插值出一个虚拟的LOAM pose PG' ,其timestamp = PG的timestamp. 然后GPS的pose ...
- git bash 乱码问题之解决方案
解决办法:右击左上方git标识,然后进入到如图中,点击Text,进行操作. 操作完毕后,关闭git bash,然后再重新打开,执行ls或ll命令,查看对应的以中文作为目录或文件名是否显示乱码,如果之前 ...
- Python学习教程(十)精选 TOP45 值得学习的Python项目
精选 TOP45 值得学习的Python项目 [导读]热门资源博客 Mybridge AI 比较了 18000 个关于 Python 的项目,并从中精选出 45 个最具竞争力的项目.我们进行了翻译,在 ...
- 转载:Linux命令行快捷键
常用 Ctrl + 左右键:在单词之间跳转 Ctrl + A:跳到本行的行首 Ctrl + E:跳到页尾 Ctrl + U:删除当前光标前面的所有文字(还有剪切功能) Ctrl + K:删除当前光标后 ...
- 【转】Selenium 报错:Element is not clickable at point的解决办法
天一同学在写Selenium Java脚本时遇到一个问题,登录进入系统之后,要点击左侧的一个菜单,但是执行到该语句时报下面的错误: Firefox中报错如下:org.openqa.selenium.E ...
- [转帖]spring、springMvc、springBoot和springCloud的联系与区别
spring.springMvc.springBoot和springCloud的联系与区别 -- :: 尘光掠影 阅读数 文章标签: springspringmvcspringbootspringCl ...
- [转帖]深度剖析一站式分布式事务方案 Seata-Server
深度剖析一站式分布式事务方案 Seata-Server https://www.jianshu.com/p/940e2cfab67e 金融级分布式架构关注 22019.04.10 16:59:14字数 ...
- Ubuntu Docker搭建GitLab以及常规配置使用
安装启动实例 1.首先创建一个目录用于存放配置 sudo docker pull docker.io/gitlab/gitlab-ce sudo mkdir -p /root/docker/gitla ...
- CSP2019退役记
写在前面 all last,我又失败了,我退役了 回忆我这个菜鸡OI生涯,有看机房神仙切题的乐趣,也有自己考场爆炸的辛酸 NOIP2017,我第一次参赛,我pj205二等打铁 NOIP2018,我第二 ...