Codeforces I. Vessels(跳转标记)
题目描述:
Vessels
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
There is a system of n vessels arranged one above the other as shown in the figure below. Assume that the vessels are numbered from 1 to n, in the order from the highest to the lowest, the volume of the i-th vessel is a**i liters.

Initially, all the vessels are empty. In some vessels water is poured. All the water that overflows from the i-th vessel goes to the (i + 1)-th one. The liquid that overflows from the n-th vessel spills on the floor.
Your task is to simulate pouring water into the vessels. To do this, you will need to handle two types of queries:
- Add x**i liters of water to the p**i-th vessel;
- Print the number of liters of water in the k**i-th vessel.
When you reply to the second request you can assume that all the water poured up to this point, has already overflown between the vessels.
Input
The first line contains integer n — the number of vessels (1 ≤ n ≤ 2·105). The second line contains n integers a1, a2, ..., a**n — the vessels' capacities (1 ≤ a**i ≤ 109). The vessels' capacities do not necessarily increase from the top vessels to the bottom ones (see the second sample). The third line contains integer m — the number of queries (1 ≤ m ≤ 2·105). Each of the next m lines contains the description of one query. The query of the first type is represented as "1 p**i x**i", the query of the second type is represented as "2 k**i" (1 ≤ p**i ≤ n, 1 ≤ x**i ≤ 109, 1 ≤ k**i ≤ n).
Output
For each query, print on a single line the number of liters of water in the corresponding vessel.
Examples
Input
Copy
25 1061 1 42 11 2 51 1 42 12 2
Output
Copy
4
5
8
Input
Copy
35 10 861 1 122 21 1 61 3 22 22 3
Output
Copy
7
10
5
思路:
这道题是让模拟一下水流的过程,不断操作,或者往一个槽子加水,或者询问某个槽子的水量。
首先一个最最朴实的想法是:建立数组模拟水流过程,若水满了,往下一个槽子流即可。但是在测试点8就回超时。显然还有优化的余地。
怎么优化呢?然后就开始了冥思苦想的过程,想到往一个槽子里的水加满后,实际上以后再往这个槽子里加水就可以忽略这个槽子了,不只是这个,由于槽子中的水不会减少,水流过程中的满的槽子均可以忽略。怎么实现呢?我首先想到了链表,不断可以摘除满的节点,从而使遍历更快捷。但是如果这样该怎么跟槽子的编号对应呢?比如我1到5号,其中3号已满,我删了之后以后如果再从3号倒水我怎么知道他该从哪个槽子开始倒呢?
又想了想前缀和。我们可以维护一个水流槽子的前缀和,比如样例1,有5,10,8,前缀和是5,15,23,只有当流过1的水流大于5才会流到2号槽子中,大于15才会流到3号槽子中,大于23才会往后面的槽子流。就累计一下从1开始流的总水量,下一次如果是从1开始流的话我们就立刻在1的前缀和中二分查找(单调性)到接下来该往哪个槽子流。这样一想,岂不是要维护2*10^5个前缀和,而且由于每次pour的起点不一样,维护操作可能会十分复杂。
其实最终的思路和思路一是一致的,区别在于实现上。实际上我们并不需要在物理上删除这个节点,只要在逻辑上跳过它就行了。我们建立一个nxt数组,来实现逻辑上的跳转。每次pour都把已满的槽子的nxt最终指向最近的未满槽子。那么每次再从满的槽子pour的时候不用一个一个遍历,而直接跳转到未满的下一个槽子了。
代码:
郁闷,非常郁闷,我把最终循环出来的起点设置为pour起点p的前面一个位置就一直T38,改为起点p就AC了。为什么嘞?因为啊,如果p出来是1,nxt[p]本来是2,nxt[p-1]=nxt[0],这个值没有意义,也没有设置过,就是默认的0,于是,t=nxt[0],循环里面nxt[0]=i;j=t=0;也就是一直都是t=0在无限循环,直到超时。我原先的想法是,既然p这个位置满了,那它之前的下次流出的时候的nxt也应该跳转,可以节省一次循环,但由于忘记考虑特殊的0点,(其实是考虑了,但是觉得没错,(:з」∠)),就陷入了死循环,如果把nxt[0]改为1应该就好了。注意考虑边界条件。
#include <iostream>
#include <cstdio>
#define max_n 200005
using namespace std;
int n,m;
long long a[max_n];
long long b[max_n];
long long nxt[max_n];
template <typename T>
inline void read(T& x)
{
x=0;int f = 0;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=1;ch=getchar();}
while('0'<=ch&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
x=f?-x:x;
}
#pragma optimize(2)
int main()
{
read(n);
for(int i = 1; i<=n; i++)
{
read(a[i]);
nxt[i] = i+1;
}
nxt[n+1]=n+1;
read(m);
while(m--)
{
int st;
read(st);
switch(st)
{
case 1:
{
int p;
long long x;
read(p);
read(x);
int i;
long long sum = 0;
for(i = p; i<=n; i=nxt[i])
{
//cout << "x " << x << " i " << i << " a[i] " << a[i] << " b[i] " << b[i] << endl;
if(b[i]+x<=a[i])
{
b[i] += x;
break;
}
sum = x+b[i]-a[i];
b[i] = a[i];
x = sum;
}
int t;
if(a[i]==b[i])i=nxt[i];
for(int j = p; j<i; j=t)//p改为p-1就T了
{
t = nxt[j];
nxt[j] = i;
}
/*cout << "next ";
for(int i = 1;i<=n;i++)
{
cout << nxt[i] << " ";
}
cout << endl;*/
break;
}
case 2:
int k;
read(k);
printf("%I64d\n",b[k]);
break;
}
}
return 0;
}
参考文章:
码代码的猿猿的AC之路,CodeForces 371D. Vessels,https://blog.csdn.net/ck_boss/article/details/17249213
Codeforces I. Vessels(跳转标记)的更多相关文章
- CodeForces 371D. Vessels
暴力+胡乱优化就过了..tags给的东西似乎什么都没用到.....CF的数据是不是有点水啊.....果然是没有营养的题目..... D. Vessels time limit per test 2 s ...
- Military Problem CodeForces - 1006E(dfs搜一下 标记一下)
题意: 就是有一颗树 然后每次询问 父结点 的 第k个结点是不是他的子嗣...是的话就输出这个子嗣..不是 就输出-1 解析: 突然想到后缀数组的sa 和 x的用法..就是我们可以用一个id标记当前 ...
- Codeforces 371D Vessels (模拟)
题目链接 Vessels 这道题我做得有点稀里糊涂啊==TLE了几发之后改了一行就A了. 具体思路就是记fi为若第i个容器已经盛不下水了,那么接下来盛水的那个容器. hi为若现在要给i号容器加水,当前 ...
- Codeforces 444C 线段树 懒惰标记
前天晚上的CF比赛div2的E题,很明显一个线段树,当时还在犹豫复杂度的问题,因为他是区间修改和区间查询,肯定是要用到懒惰标记. 然后昨天真的是给这道题跪了,写了好久好久,...我本来是写了个add标 ...
- CodeForces 371D Vessels(树状数组)
树状数组,一个想法是当往p注水时,认为是其容量变小了,更新时二分枚举,注意一些优化. #include<cstdio> #include<iostream> #include& ...
- for或者while的标记循环
for或者while的标记循环 今天在写代码的时候,发现一个for循环前有一个字母,不知道这个是什么语法,后来查了一下,这个语法是用来实现标记循环的功能 这个是代码块 r:for(int rowNum ...
- springMVC源码分析--页面跳转RedirectView(三)
之前两篇博客springMVC源码分析--视图View(一)和springMVC源码分析--视图AbstractView和InternalResourceView(二)中我们已经简单的介绍了View相 ...
- gvim -- 跳转命令,查找格式,正则
1.跳转命令 ‘w'单词前进,'b'单词后退,'e'单词前进,‘ge’单词后退,存在单词词首词尾区别,'W''B''E''gE'将不以单词区分,以空格区分 ‘$’行尾,'^'非空白行首,'0'行首 ‘ ...
- Pytest系列(7) - skip、skipif跳过用例
如果你还想从头学起Pytest,可以看看这个系列的文章哦! https://www.cnblogs.com/poloyy/category/1690628.html 前言 pytest.mark.sk ...
随机推荐
- [MySQL] MySQL存储过程 事务transaction 数据表重建
直接上代码 -- 删除存储过程 DROP PROCEDURE IF EXISTS `renew_message_queue`; -- 添加; 的转义 DELIMITER ;; CREATE PROCE ...
- Entity Framework Core for Console
包 Microsoft.EntityFrameworkCore Microsoft.EntityFrameworkCore.SqlServer Microsoft.EntityFrameworkCor ...
- IIS配置实现反向代理(图文)
需求: 网站在备案,本来的网站不符合要求,先反向到别的网站.原网站:test.com, 目标网站:target.com 设置反向代理的服务器一定是在原网站服务器上. 注意:iis应该是iis7及以上版 ...
- iOS史上最简单修改导航栏分隔线颜色方法!!!
override func viewDidLoad() { super.viewDidLoad() if let imageView = self.findNavLineView(view: navi ...
- .net桌面程序或者控制台程序使用NLog时的注意事项
Nuget添加NLog 添加nlog.config文件,并选择属性->始终复制 不选择始终复制,编译后nlog.config是没有的. 具体使用: private static readonly ...
- [转帖]dfs和bfs
dfs和bfs https://www.cnblogs.com/wzl19981116/p/9397203.html 1.dfs(深度优先搜索)是两个搜索中先理解并使用的,其实就是暴力把所有的路径都搜 ...
- 如何Dockerize您的端到端验收测试
本文作为使用Selenium Docker映像以及CodeceptJS和Express服务器的“操作方法”指南. 其中,我们将涵盖: 什么是E2E验收测试? 为什么要使用Docker? 松散耦合的测试 ...
- Python知识点总结篇(五)
软件目录结构规范 目标: 提高可读性: 提高可维护性: 常见结构 Demo/ |-- bin/ #存放项目的一些可执行文件 | |-- demo #可执行程序,启动demo调main.py | |-- ...
- MNIST机器学习入门(二)
在前一个博客中,我们已经对MNIST 数据集和TensorFlow 中MNIST 数据集的载入有了基本的了解.本节将真正以TensorFlow 为工具,写一个手写体数字识别程序,使用的机器学习方法是S ...
- go 程序整个执行过程