列表

详情


WY72. 香槟塔

描述

节日到啦,牛牛和妞妞邀请了好多客人来家里做客。
他们摆出了一座高高的香槟塔,牛牛负责听妞妞指挥,往香槟塔里倒香槟。
香槟塔有个很优雅的视觉效果就是如果这一层的香槟满了,就会从边缘处往下一层流去。
妞妞会发出两种指令,指令一是往第x层塔内倒体积为v的香槟,指令二是询问第k层塔香槟的体积为多少。
告诉你香槟塔每层香槟塔的初始容量,你能帮牛牛快速回答妞妞的询问吗?

输入描述

第一行为两个整数n,m。表示香槟塔的总层数和指令条数。
第二行为n个整数ai,表示每层香槟塔的初始容量。
第三行到第2+m行有两种输入,一种输入是“2 x v”表示往第x层倒入体积为v的香槟;另一种输入是“1 k”表示询问第k层当前有多少香槟。
1 <= n, m <= 1000。
1 <= n ,m <= 200000,1 <= ai ,v <= 1000000000。

输出描述

对于每个询问,输出一个整数,表示第k层香槟的容量。

示例1

输入:

1 2
8
2 1 9
1 1

输出:

8

示例2

输入:

5 4
1 2 2 10 1
1 3
2 2 5
2 4 3
1 4

输出:

0
4

原站题解

C++ 解法, 执行用时: 74ms, 内存消耗: 4744KB, 提交时间: 2021-08-25

#include<stdio.h>
#include<functional>
using namespace std;
using ll = long long;
#define N 200001
ll v[N];
ll p[N];
int to[N];
int main()
{
    int n, m;
    while (~scanf("%d%d", &n, &m))
    {
        for (int i = 1; i <= n; ++i)
        {
            scanf("%d", &v[i]);
            p[i] = 0;
            to[i] = i;
        } 
        function<int(int,ll,int)> Add = [&](int x, ll y, int k)
        {
            if (x > n) return n+1;
            if (p[x] == v[x] && to[x] != x)
            {
                to[x] = Add(to[x], y, k+1);
            }
            else 
            {
                if (p[x]+y >= v[x])
                    to[x] = Add(x+1, p[x]+y-v[x], k+1);
                p[x] = min(p[x]+y, v[x]);
            }
            return to[x];
        };
        int t;
        for (int i = 0; i < m; ++i)
        {
            int x, y;
            scanf("%d%d", &t, &x);
            if (t == 2) scanf("%d", &y);
            if (t == 1) printf("%d\n", p[x]);
            else Add(x, y, 0);
        }
    }
}

C++ 解法, 执行用时: 79ms, 内存消耗: 3192KB, 提交时间: 2020-10-29

#include<bits/stdc++.h>

const int MAXN=200015;

using namespace std;
int mark[MAXN],a[MAXN],b[MAXN];

int _find(int x){
    if(x==0)return x;
    if(a[x]!=b[x])return x;
    return mark[x]=mark[x+1]=_find(mark[x+1]);
}

int main(){
    int n,m,x,y,d;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
        b[i]=0;
        mark[i]=i;
    }
    int op;
    while(m--){
        scanf("%d",&op);
        if(op==2){
            scanf("%d%d",&x,&y);
            while(y){
                x=_find(x);
                if(x==0)break;
                d=min(a[x]-b[x],y);
                b[x]+=d;
                y-=d;
            }
        }else{
            scanf("%d",&x);
            printf("%d\n",b[x]);
        }
    }
    return 0;
}

上一题