线段数求调0pts

P3372 【模板】线段树 1

Pangding @ 2024-01-13 15:21:20

#include<bits/stdc++.h>
#define int long long  
//线段树模板——区间和
using namespace std;

int a[400010];

struct treenode {
    int value;
    int lazytag;
    int l,r;
} treenode[500010];

void pushdown(int k) {
    int mid=(treenode[k].l+treenode[k].r)>>1;
    treenode[k*2].lazytag=treenode[k].lazytag;
    treenode[k*2].value+=(mid-treenode[k].l+1)*treenode[k*2].lazytag;
    treenode[k*2+1].lazytag=treenode[k].lazytag;
    treenode[k*2+1].value+=(treenode[k].r-mid)*treenode[k*2+1].lazytag;
    treenode[k].lazytag=0;
}

void build(int k,int l,int r) { //递归建树
    treenode[k].l=l;
    treenode[k].r=r;
    if(l==r) {
        treenode[k].value=a[l];
        return;
    }
    int mid=(l+r)>>1;
    build(k*2,l,mid);
    build(k*2+1,mid+1,r);
    treenode[k].value=treenode[k*2].value+treenode[k*2+1].value;
    //更新
}

void update(int k,int l,int r,int v) {
    if(treenode[k].l==l&&treenode[k].r==r) {
        pushdown(k);
        treenode[k].value+=v*(treenode[k].r-treenode[k].l+1);
        treenode[k].lazytag=v;
        return;
    }
    int mid=(treenode[k].l+treenode[k].r)>>1;
    if(r<=mid) {
        update(k*2,l,r,v);
    } else if(l>mid) {
        update(k*2+1,l,r,v);
    } else {
        update(k*2,l,mid,v);
        update(k*2+1,mid+1,r,v);
    }
    treenode[k].value=treenode[k*2].value+treenode[k*2+1].value;
}
/*
int query(int k,int l,int r) { //傻逼区间覆盖去死吧!
    if(l<=treenode[k].l&&r>=treenode[k].r) {

        return treenode[k].maxn;
    }
    int mid=(treenode[k].l+treenode[k].r)>>1;
    int maxn=-inf;
    if(l<=mid) {
        maxn=max(maxn,query(k*2,l,r));
    }
    if(r>mid) {
        maxn=max(maxn,query(k*2+1,l,r));
    }
    return maxn;
}
*/
int query(int k,int l,int r) {
    if(l==treenode[k].l&&r==treenode[k].r) {
        return treenode[k].value;
    }
    int mid=(treenode[k].l+treenode[k].r)>>1;
    if(r<=mid) {
        pushdown(k);
        return query(k*2,l,r);
    } else if(l>mid) {
        pushdown(k);
        return query(k*2+1,l,r);
    } else {
        pushdown(k);
        return query(k*2,l,mid)+query(k*2+1,mid+1,r);
    }
}

signed main() {
    int n,m;
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        cin>>a[i];
    }
    build(1,1,n);
    while(m--){
        int a,b,c,d;
        cin>>a>>b>>c;
        if(a==1){
            cin>>d; 
            update(1,b,c,d);
        }
        else{
            cout<<query(1,b,c)<<endl;
        }
    } 
    return 0;
}

by __PRO__ @ 2024-01-13 16:01:29

@I_AK_IOI_2029 你的change和query问题很大; 我这里附上我的代码:

void add(int& p, int l, int r, int x, int y, ll d)
{
    if (!p)
        p = ++cnt;
    if (x <= l && r <= y) {
        t[p].sum += d * (r - l + 1);
        t[p].tag += d;
        return;
    }
    pushdown(p, l, r);
    int mid = (l + r) >> 1;
    if (x <= mid)
        add(t[p].l, l, mid, x, y, d);
    if (mid < y)
        add(t[p].r, mid + 1, r, x, y, d);
    pushup(p);
}
ll query(int& p, int l, int r, int x, int y)
{
    if (!p)
        p = ++cnt;
    if (x <= l && r <= y)
        return t[p].sum;
    pushdown(p, l, r);
    int mid = (l + r) >> 1;
    ll sum = 0;
    if (x <= mid)
        sum += query(t[p].l, l, mid, x, y);
    if (mid < y)
        sum += query(t[p].r, mid + 1, r, x, y);
    return sum;
}

你自己看吧。


|