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;
    }
    

      

  • 相关阅读:
    SQL跨服查询
    SQL时间函数
    MFC控件添加变量,control和value的区别
    error LNK2001 unresolved external symbol
    VS中C++代码折叠
    ERROR 2003 (HY000): Can't connect to MySQL server
    vs2012换肤功能,vs2012主题及自定义主题
    MFC、SDK和API有什么区别
    寻找子字符串int find_substr(char *s1, char *s2)
    document.title 跑马灯效果
  • 原文地址:https://www.cnblogs.com/IMGavin/p/5769074.html
Copyright © 2011-2022 走看看