Codeforces Round #218 (Div. 2) D. Vessels

来源:互联网 发布:微信pc客户端 mac 编辑:程序博客网 时间:2024/04/26 08:11
D. 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 ton, in the order from the highest to the lowest, the volume of thei-th vessel is ai liters.

Initially, all the vessels are empty. In some vessels water is poured. All the water that overflows from thei-th vessel goes to the(i + 1)-th one. The liquid that overflows from then-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 xi liters of water to thepi-th vessel;
  2. Print the number of liters of water in the ki-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 containsn integers a1, a2, ..., an — the vessels' capacities (1 ≤ ai ≤ 109). The vessels' capacities do not necessarily increase from the top vessels to the bottom ones (see the second sample). The third line contains integerm — the number of queries (1 ≤ m ≤ 2·105). Each of the nextm lines contains the description of one query. The query of the first type is represented as "1pixi", the query of the second type is represented as "2ki" (1 ≤ pi ≤ n,1 ≤ xi ≤ 109,1 ≤ ki ≤ n).

Output

For each query, print on a single line the number of liters of water in the corresponding vessel.

Sample test(s)
Input
25 1061 1 42 11 2 51 1 42 12 2
Output
458
Input
35 10 861 1 122 21 1 61 3 22 22 3
Output
7105

 

题意:给一个从上到下的漏斗,当漏斗一满时,就会溢到下一个漏斗(就算下一个小过上面的一个也一样漏到下一个),然后他给你两种状态,一种是注水,一种是查询

其实查询很简单,就是维护一个数组代表着n个漏斗的水量。然后直接查询就行了。最重要的是如何最多在nlog(n)的条件下可以维护数组。刚开始我写的很暴力,n^2,超时了

其实这道题就是人工模拟链表。用数组来维护链表的指针。然后更新。。

反省一下:下次要不断地思考问题。因为一道acm的题目不仅要会算法还要懂得分析这道题的解决思路,这才是王道。还有自己做题速度实在是太慢了。。

附我ac代码

#include<cstdio>#include<cstring>int nv[200009],v[200009];int f[200009],go[200009];int main(){    int n,i,j,k,vv,m;    while(~scanf("%d",&n))    {        memset(nv,0,sizeof(nv));        for(i=0;i<n;i++)        {            scanf("%d",&v[i]);            go[i] = i+1;        }        scanf("%d",&m);        int select;        for(i=0;i<m;i++)        {            scanf("%d",&select);            if(select==2)            {                scanf("%d",&k);                printf("%d\n",nv[k-1]);            }            else            {                scanf("%d%d",&k,&vv);                k--;                int kk = k;                int r = 0;                            while(vv>0 && kk<n)                {                                        if(vv<=v[kk]-nv[kk])                    {                        nv[kk] += vv;                        vv = 0;                    }                    else                    {                        vv -= (v[kk]-nv[kk]);                        nv[kk] = v[kk];                        f[r++] = k;                        kk = go[kk];                                            }                                    }                for(j=0;j<r;j++)                    go[f[j]] = kk;             }        }    }    return 0;}


TLE代码

#include<cstdio>#include<cstring>int nv[200009],v[200009];int f[200009];int main(){int n,i,j,k,vv,m;while(~scanf("%d",&n)){memset(f,0,sizeof(f));for(i=1;i<=n;i++){scanf("%d",&v[i]);nv[i] = v[i];}scanf("%d",&m);int select;for(i=0;i<m;i++){scanf("%d",&select);if(select==2){scanf("%d",&k);printf("%d\n",nv[k]-v[k]);}else{scanf("%d%d",&k,&vv);while(vv>0 && k<=n){if(!f[k]){if(vv>=v[k]){vv-=v[k];v[k] = 0;f[k] = 1;}else{v[k]-=vv;vv = 0;}}k++;}}}}return 0;}


 

 

 

1 0
原创粉丝点击