样例过了 三十求条 玄关

P3372 【模板】线段树 1

xiaozhichen123 @ 2024-11-16 20:14:33

#include<bits/stdc++.h>
using namespace std;
#define int long long
int n, m, a[10000001], b[10000001], x, k, y, q, ans, c[100000001];
void tree(int l, int r, int x) {
    if (l < r) { //还能继续二分建树
        int mid = l + (r - l) / 2; //讲数据分成两份,放在节点的左下节点和右下节点
        tree(l, mid, x * 2); //节点的左下节点处继续分
        tree(mid + 1, r, x * 2 + 1); //节点的右下节点处继续分
        b[x] = b[x * 2] + b[x * 2 + 1]; //递归回来后x节点的值为子节点的值的和    所有子节点的区间和
    } else {
        b[x] = a[l]; //叶节点赋值
    }
}
int inquire(int ll, int rr, int l, int r, int x) { //查询
    int mid = ll + (rr - ll) / 2;
    if (c[x] != 0) { //此节点有lazy
        int sum = rr - ll + 1; //求区间的范围,以用来的整个区间所得的和
        b[x] += sum * c[x]; //此区间所得的和等于所有包含节点的个数*每个节点所加的数
        c[x * 2] = c[x * 2 + 1] = c[x]; //将lazy标记向下传递
        c[x] = 0; //清除lazy标记
    }
    if (ll == l && rr == r) { //当查到要查的区间时返回
        return b[x];
    }
    if (r <= mid) { //当区间全在左边时只继续查左边  注意:“<=”是因为mid的位置在左边
        return inquire(ll, mid, l, r, x * 2); //继续查左边
    }
    if (l > mid) { //当区间全在右边时只继续查右边  注意:“>”是因为mid的位置在左边
        return inquire(mid + 1, rr, l, r, x * 2 + 1); //继续查右边
    }
    if (r > mid && l <= mid) { //当区间部分在左,部分在右时,即mid在区间内,既要查左边,又要查右边
        return inquire(ll, mid, l, mid, x * 2) + inquire(mid + 1, rr, mid + 1, r, x * 2 + 1); //左边的区间和加右边的区间和
    }
}
void pplus(int ll, int rr, int l, int r, int x, int num) { //区间加法(实际上只是加上lazy标记)
    int mid = ll + (rr - ll) / 2;
    b[x] += (r - l + 1) * num;
    if (ll == l && rr == r) { //区间完全重合
        c[x * 2+1] += num;
        c[x * 2] += num; //lazy标记赋值
    } else if (r <= mid) {
        pplus(ll, mid, l, r, x * 2, num); //向左查找
    } else if (l > mid) {
        return pplus(mid + 1, rr, l, r, x * 2 + 1, num); //向右查找
    } else if (r > mid && l <= mid) { //分割向两边查找
        pplus(ll, mid, l, mid, x * 2, num);
        pplus(mid + 1, rr, mid + 1, r, x * 2 + 1, num);
    }
}
signed main() {
    cin >> n >> m;
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
    }
    tree(1, n, 1);
    for (int i = 1; i <= m; i++) {
        cin >> q;
        //cout << endl;
    //  cout << endl;
        if (q == 2) {
            cin >> x >> y;
            //cout << endl;
            cout << inquire(1, n, x, y, 1) << endl; //进入查询
        }
        if (q == 1) {
            cin >> x >> y >> k;
            pplus(1, n, x, y, 1, k); //进入加法
        }
//      int m = 1;
//      cout << endl;
//      cout << endl;
//      for (int i = 1; i <= 9; i++) {
//          if (i == m * 2) {
//              cout << endl;
//              m = i;
//          }
//          cout << b[i] << " " << c[i] << " ";
//      }
//      cout << endl;
//      cout << endl;
    }
}

by __Refine__ @ 2024-11-21 20:27:04

看来已经找到了


上一页 |