线段树板子

线段树单点修改 区间求和模板

//线段树单点修改,区间查询
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define MAXN 100005
using namespace std;
using std::cin;
using std::cout;
int n,m;
char ch;

struct T{
    int l,r;
    long long val;
}t[MAXN*4];

inline void updata(int node){
    t[node].val=t[node<<1].val+t[node<<1|1].val;
}

inline void build(int l,int r,int node){
    t[node].l=l;
    t[node].r=r;
    if(l==r){
        t[node].val=a[l];
        return;
    }
    int mid=(l+r)/2;
    build(l,mid,node<<1);
    build(mid+1,r,node<<1|1);
    updata(node);
}

inline void change(int p,int node,int k){
    if(t[node].l==t[node].r){
        t[node].val+=k; 
        return;
    }
    int mid=(t[node].l+t[node].r)>>1;
    if(p<=mid)change(p,node<<1,k);
    else change(p,node<<1|1,k); 
    updata(node);
}

inline long long ask(int l,int r,int node){
    long long ans=0;
    if(l<=t[node].l&&t[node].r<=r){
        return t[node].val;
    }
    int mid=(t[node].l+t[node].r)>>1;
    if(l<=mid)ans+=ask(l,r,node<<1);
    if(r>mid)ans+=ask(l,r,node<<1|1);
    return ans;
}

int main(){
    scanf("%d%d",&n,&m);
    build(1,n,1);
    for(int i=1;i<=m;i++){
        int x,y;
        cin>>ch>>x>>y;
        if(ch=='x'){
            change(x,1,y);
        }
        else{
            cout<<ask(x,y,1)<<endl;
        }
    }

    return 0;
}

单点修改 区间查询最大值

LYOI Cat ring
打出线段树单点修改区间求和模板,然后将更新函数,建树函数,查询函数中原先的求和改成取max即可。

//线段树单点修改,区间查询
#include <bits/stdc++.h>
#define int long long
#define MAXN 1000005
using namespace std;
using std::cin;
using std::cout;
int n, m;
char ch;
int a[MAXN];
struct T {
    int l, r;
    long long maxn;
} t[MAXN * 4];

inline void updata(int node) { t[node].maxn = max(t[node << 1].maxn, t[node << 1 | 1].maxn); }

inline void build(int l, int r, int node) {
    t[node].l = l;
    t[node].r = r;
    if (l == r) {
        t[node].maxn = a[l];
        return;
    }
    int mid = (l + r) / 2;
    build(l, mid, node << 1);
    build(mid + 1, r, node << 1 | 1);
    updata(node);
}

inline void change(int p, int node, int k) {
    if (t[node].l == t[node].r) {
        t[node].maxn += k;
        return;
    }
    int mid = (t[node].l + t[node].r) >> 1;
    if (p <= mid)
        change(p, node << 1, k);
    else
        change(p, node << 1 | 1, k);
    updata(node);
}

inline long long ask(int l, int r, int node) {
    long long ans = 0;
    if (l <= t[node].l && t[node].r <= r) {
        return t[node].maxn;
    }
    int mid = (t[node].l + t[node].r) >> 1;
    if (l <= mid)
        ans = max(ask(l, r, node << 1), ans);
    if (r > mid)
        ans = max(ask(l, r, node << 1 | 1), ans);
    return ans;
}

signed main() {
    freopen("ring.in", "r", stdin);
    freopen("ring.out", "w", stdout);
    cin >> n >> m;
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
    }
    build(1, n, 1);
    int op, x, y;
    for (int i = 1; i <= m; i++) {
        cin >> op >> x >> y;
        if (op == 1) {
            change(x, 1, y);
        }

        else {
            if (x <= y)
                printf("%lld\n", ask(x, y, 1));
            else
                printf("%lld\n", max(ask(x, n, 1), ask(1, y, 1)));
        }
    }

    return 0;
}
posted @ 2022-09-02 10:15  DAIANZE  阅读(22)  评论(0编辑  收藏  举报