题目描述:

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:

  1. Add x**i liters of water to the p**i-th vessel;
  2. 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(跳转标记)的更多相关文章

  1. CodeForces 371D. Vessels

    暴力+胡乱优化就过了..tags给的东西似乎什么都没用到.....CF的数据是不是有点水啊.....果然是没有营养的题目..... D. Vessels time limit per test 2 s ...

  2. Military Problem CodeForces - 1006E(dfs搜一下 标记一下)

    题意: 就是有一颗树  然后每次询问 父结点 的 第k个结点是不是他的子嗣...是的话就输出这个子嗣..不是 就输出-1 解析: 突然想到后缀数组的sa 和 x的用法..就是我们可以用一个id标记当前 ...

  3. Codeforces 371D Vessels (模拟)

    题目链接 Vessels 这道题我做得有点稀里糊涂啊==TLE了几发之后改了一行就A了. 具体思路就是记fi为若第i个容器已经盛不下水了,那么接下来盛水的那个容器. hi为若现在要给i号容器加水,当前 ...

  4. Codeforces 444C 线段树 懒惰标记

    前天晚上的CF比赛div2的E题,很明显一个线段树,当时还在犹豫复杂度的问题,因为他是区间修改和区间查询,肯定是要用到懒惰标记. 然后昨天真的是给这道题跪了,写了好久好久,...我本来是写了个add标 ...

  5. CodeForces 371D Vessels(树状数组)

    树状数组,一个想法是当往p注水时,认为是其容量变小了,更新时二分枚举,注意一些优化. #include<cstdio> #include<iostream> #include& ...

  6. for或者while的标记循环

    for或者while的标记循环 今天在写代码的时候,发现一个for循环前有一个字母,不知道这个是什么语法,后来查了一下,这个语法是用来实现标记循环的功能 这个是代码块 r:for(int rowNum ...

  7. springMVC源码分析--页面跳转RedirectView(三)

    之前两篇博客springMVC源码分析--视图View(一)和springMVC源码分析--视图AbstractView和InternalResourceView(二)中我们已经简单的介绍了View相 ...

  8. gvim -- 跳转命令,查找格式,正则

    1.跳转命令 ‘w'单词前进,'b'单词后退,'e'单词前进,‘ge’单词后退,存在单词词首词尾区别,'W''B''E''gE'将不以单词区分,以空格区分 ‘$’行尾,'^'非空白行首,'0'行首 ‘ ...

  9. Pytest系列(7) - skip、skipif跳过用例

    如果你还想从头学起Pytest,可以看看这个系列的文章哦! https://www.cnblogs.com/poloyy/category/1690628.html 前言 pytest.mark.sk ...

随机推荐

  1. html的rowspan和colspan

    https://www.jb51.net/article/165695.htm rowspan工具 https://blog.csdn.net/oxiaobaio/article/details/80 ...

  2. Swarm 集群并用 Portainer 管理

    https://blog.csdn.net/zhrq95/article/details/79430284 使用docker-proxy代理服务(所有节点): docker pull docker.i ...

  3. vue获取不到后端返回的响应头

    Response.ContentType = EPPlusHelpler.ExcelContentType; Response.Headers.Add("FileName", fi ...

  4. centos7修改主机名的方法

    在CentOS7中,有三种定义的主机名: 静态的(Static hostname) “静态”主机名也称为内核主机名,是系统在启动时从/etc/hostname自动初始化的主机名. 瞬态的(Tansie ...

  5. C++ 智能指针 shared_ptr 分析

    引文: C++对指针的管理提供了两种解决问题的思路: 1.不允许多个对象管理一个指针 2.允许多个对象管理一个指针,但仅当管理这个指针的最后一个对象析构时才调用delete ps:这两种思路的共同点就 ...

  6. matlab柱状图画法

    %%各时段电量需求 clc close all clear all x = [11000 33000 25000 36000 25000 30000 18000]; tick = {'0-6' '6- ...

  7. SQL Server 系统库的备份与恢复

    master数据库 master作为数据库的主要数据库,记录着SQL Server系统的所有系统级信息,例如登录用户.系统配置设置.端点和凭证以及访问其他数据服务器所需要的信息.master数据库还记 ...

  8. Python中NumPy的使用一

    NumPy简介: 一个用python实现的科学计算,包括:1.一个强大的N维数组对象Array:2.比较成熟的(广播)函数库:3.用于整合C/C++和Fortran代码的工具包:4.实用的线性代数.傅 ...

  9. windows操作系统更改 <远程桌面> 端口号

    windows远程桌面连接默认使用的是3389端口,为了避免被他人扫描从而暴力破解远程服务器或者病毒入侵.可以将默认端口修改为其它端口,如8888,11111等.最好修改为10000以后的端口,这样可 ...

  10. Maven打包时集成依赖项或复制依赖项到指定目录

    1.集成依赖项,最后生成的jar文件包含所有依赖: <build> <plugins> <plugin> <artifactId>maven-assem ...