zoukankan      html  css  js  c++  java
  • 贴代码

    #include <bits/stdc++.h>
    
    using namespace std;
    
    #define ll long long
    
    const int Maxn = 500005;
    
    int Sum[Maxn<<2],Add[Maxn<<2];//Sum求和,Add为懒惰标记
    int A[Maxn],n;//存原数组数据下标[1,n]
    
    // 建树
    void BuildTree(int i, int l, int r) {
        if(l == r) {
            Sum[i] = A[l];
            return;
        }
        int mid = (l+r)>>1;
        BuildTree(i << 1, l, mid);
        BuildTree((i << 1)+1, mid+1, r);
        Sum[i] = Sum[i << 1] + Sum[(i << 1)+1];
    }
    
    // 单点修改(二分查找)
    void Update(int pos, int k, int l, int r, int i) {
        if(l == r) {
            Sum[i] += k;
            return;
        }
        int mid = (l+r)>>1;
        if(pos <= mid) Update(pos, k, l, mid, i << 1);
        else Update(pos, k, mid+1, r, (i << 1)+1);
        Sum[i] = Sum[i << 1] + Sum[(i << 1)+1];
    }
    
    // 懒惰标记
    
    void PushDown(int rt,int ln,int rn){
        //ln,rn为左子树,右子树的数字数量。
        if(Add[rt]){
            //下推标记
            Add[rt<<1]+=Add[rt];
            Add[rt<<1|1]+=Add[rt];
            //修改子节点的Sum使之与对应的Add相对应
            Sum[rt<<1]+=Add[rt]*ln;
            Sum[rt<<1|1]+=Add[rt]*rn;
            //清除本节点标记
            Add[rt]=0;
        }
    }
    
    // 区间修改
    void UpdateDomain(int L, int R, int k, int l, int r, int i) {
        if(L <= l && R >= r) {
            Sum[i] += k*(r-l+1);
            Add[i] += k;
            return;
        }
        int mid = (l+r)>>1;
        PushDown(i, mid-l+1, r-mid);
        if(L <= mid) UpdateDomain(L, R, k, l, mid, i<<1);
        if(R > mid) UpdateDomain(L, R, k, mid+1, r, i<<1|1);
        Sum[i] = Sum[i << 1] + Sum[(i << 1)+1];
    }
    
    // 区间查询
    int Search(int L, int R, int l, int r, int i) {
    
        if(L <= l && R >= r) {
            return Sum[i];
        }
    
        int mid = (l+r)>>1;
        PushDown(i, mid-l+1,r-mid);
        int ans = 0;
        if(L <= mid) ans += Search(L, R, l, mid, i<<1);
        if(R > mid) ans += Search(L, R, mid+1, r, (i<<1)+1);
        return ans;
    }
    
    int main() {
        int x, y;
        cin >> x >> y;
        for (int i = 1; i <= x; ++i) {
            cin >> A[i];
        }
        BuildTree(1, 1, x);
        int t, op1, op2, k;
        for (int i = 0; i < y; ++i) {
            cin >> t;
            if(t == 1) {
                cin >> op1 >> op2 >> k;
                UpdateDomain(op1, op2, k, 1, x, 1);
            }
    
            if(t == 2) {
                cin >> op1;
                printf("%d
    ", Search(op1, op1, 1, x, 1));
            }
        }
        return 0;
    }
    
    
  • 相关阅读:
    关闭Windows的CTRL+ALT+DEL 和 ALT+TAB组合键的方法
    VC中常用文件操作(一)
    VC 创建NT服务程序
    几个操作文件的API函数
    VC中常用文件操作(二) ——INI文件操作
    初学OpenCV之图像坐标读取函数cvGet2D()
    OpenCV学习之图像读取与显示
    SLT容器之vector简单实现C++运行时多态
    C/C++文件——数据写入、读取
    OpenCV学习之视频读取与帧的提取、显示及保存
  • 原文地址:https://www.cnblogs.com/knightoflake/p/14475013.html
Copyright © 2011-2022 走看看