zoukankan      html  css  js  c++  java
  • CodeForces 371D Vessels(树状数组)

    树状数组,一个想法是当往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
    ", cap[k] - rem[k]);
            }
    
        }
        return 0;
    }
    

      

  • 相关阅读:
    使用PDO连接数据库
    ES6 promise
    弹框小三角
    封装弹窗功能
    css3 省略号
    使mac支持NTFS读写问题
    Vue 打包 build 前需要修改哪些配置和路径
    eslint配置大全
    在elementUI中使用 el-autocomplete 实现远程搜索的下拉框
    element-UI table自定义表头
  • 原文地址:https://www.cnblogs.com/IMGavin/p/5769074.html
Copyright © 2011-2022 走看看