CodeForces 371D Vessels(树状数组)

时间:2021-10-25 10:25:13

树状数组,一个想法是当往p注水时,认为是其容量变小了,更新时二分枚举,注意一些优化。

 

 

#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<string>
#include<algorithm>
#include<map>
#include<queue>
#include<vector>
#include<cmath>
#include<utility>
using namespace std;
typedef long long LL;
const int N = 200008;
const LL INF = (LL)1 << (LL)61;
#define MS(a, num) memset(a, num, sizeof(a))
#define PB(A) push_back(A)
#define FOR(i, n) for(int i = 0; i < n; i++)
LL C[N];
LL cap[N];
LL rem[N];
int n;//注意初始化n
inline int lowbit(int x){
    return x&-x;
}
inline void add(int x, LL val){
    for(int i=x;i<=n;i+=lowbit(i)){
        C[i] += val;
    }
}
inline LL sum(int x){//求1到x的和
    LL ret = 0;
    for(int i=x;i>0;i-=lowbit(i)){
        ret+=C[i];
    }
    return ret;
}
int main(){
    cin>>n;
    for(int i = 1;i <= n; i++){
        scanf("%I64d", &cap[i]);
        rem[i] = cap[i];
        add(i, cap[i]);
    }
    cap[n + 1] = INF;
    rem[n + 1] = INF;
    add(n + 1, INF);
    int m;
    cin>>m;
    int op, x,p , k;
    while(m--){
        scanf("%d", &op);
        if(op == 1){
            scanf("%d %d", &p, &x);
            int l = p, r = n +1;
            int ans = l;
            LL s  = sum(p - 1);
            int start = p;
            while(l < r){
                int mid = (l + r)>>1;
                LL s2= sum(mid) - s;
                if(s2 == 0){
                    start = mid + 1;
                }
                if(s2 < x){
                    l = mid + 1;
                }else{
                    r = mid;
                }
            }
            ans = l;
            LL s3  = sum(ans -1) - s;
            for(int i = start; i < ans ; i++){
                if(rem[i]){
                    add(i, -rem[i]);
                    rem[i]  = 0;
                }
            }
            if(x - s3){
                add(ans,-( x - s3));
                rem[ans] -= x - s3;
            }
        }else{
            scanf("%d", &k);
            printf("%I64d\n", cap[k] - rem[k]);
        }

    }
    return 0;
}