0 分求调

P3372 【模板】线段树 1

Laugh_at_the_sky @ 2024-08-16 14:05:30

#include <map>
#include <set>
#include <list>
#include <regex>
#include <queue>
#include <limits>
#include <iomanip>
#include <iostream>

#include <math.h>
#include <time.h>

using namespace std;

#define int long long

const int N = 1e5 + 5;

int n, m;
int a[N];

struct Node {
    int l, r;
    int sum;
    int tag;
};
Node operator + (const Node& a, const Node& b) {
    Node x;
    x.l = a.l;
    x.r = b.r;
    x.sum = a.sum + b.sum;

    return x;
}
Node t[N << 1 << 1];

void build(int l, int r, int rt) {
    if (l == r) {
        t[rt].l = t[rt].r = l;
        t[rt].sum = a[l];
        return;
    }
    int m = (l + r) >> 1;
    build(l, m, rt << 1);
    build(m + 1, r, rt << 1 | 1);
    t[rt] = t[rt << 1] + t[rt << 1 | 1];
}

void color(int rt, int x) {
    t[rt].sum += (t[rt].r - t[rt].l + 1) * x;
    t[rt].tag += x; 
}
void color_son(int rt) {
    if (t[rt].tag) {
        color(rt << 1, t[rt].tag);
        color(rt << 1 | 1, t[rt].tag);
        t[rt].tag = 0;
    }
}

Node query(int l, int r, int rt, int nl, int nr) {
    if (l >= nl && r <= nr) 
        return t[rt];
    color_son(rt);
    int m = (l + r) >> 1;
    if (nl <= m) {
        if (m < nr) 
            return query(l, m, rt << 1, nl, nr) + query(m + 1, r, rt << 1 | 1, nl, nr);
        else 
            return query(l, m, rt << 1, nl, nr);
    }
    else 
        return query(m + 1, r, rt << 1 | 1, nl, nr);
}
void update(int l, int r, int rt, int nl, int nr, int x) {
    if (l >= nl && r <= nr) {
        color(rt, x);
        return;
    }
    color_son(rt);
    int m = (l + r) >> 1;
    if (nl <= m) update(l, m, rt << 1, nl, nr, x);
    if (nr > m) update(m + 1, r, rt << 1 | 1, nl, nr, x);
    t[rt] = t[rt << 1] + t[rt << 1 | 1];
}

signed main() {
    cin >> n >> m;
    for (int i = 1; i <= n; i++)
        cin >> a[i];
    build(1, n, 1);
    while (m--) {
        int op;
        cin >> op;
        int x, y;
        cin >> x >> y;
        if (op == 1) {
            int k;
            cin >> k;
            update(1, n, 1, x, y, k);
        }
        if (op == 2)
            cout << query(1, n, 1, x, y).sum << "\n";
    }

    return 0;
}

by Laugh_at_the_sky @ 2024-08-16 14:07:47

样例过了,下载的第一个测试点的数据也过了,但就是 WA。


by cqbzpyl @ 2024-08-16 14:21:14

@Laugh_at_the_sky build()里面,把 t[p].l=l,t[p].r=r; 放 if 外面去


by Laugh_at_the_sky @ 2024-08-16 14:26:00

void build(int l, int r, int rt) {
    t[rt].l = l;
    t[rt].r = r;
    if (l == r) {
        t[rt].sum = a[l];
        return;
    }
    int m = (l + r) >> 1;
    build(l, m, rt << 1);
    build(m + 1, r, rt << 1 | 1);
    t[rt] = t[rt << 1] + t[rt << 1 | 1];
}

这样?


by Laugh_at_the_sky @ 2024-08-16 14:26:11

@cqbzpyl


by cqbzpyl @ 2024-08-16 14:26:19

@Laugh_at_the_sky 餐烤代码

#include<bits/stdc++.h>
using namespace std;
int a[1000010],n,d;
struct node{
    int l,r;
    long long sum,add;
}t[4000010];
void build(int p,int l,int r){//建树 
    t[p].l=l,t[p].r=r;
    if(l==r){
        t[p].sum=a[l];
        return;
    }
    int tm=(l+r)>>1;
    build(p<<1,l,tm);
    build(p<<1|1,tm+1,r);

    t[p].sum=t[p<<1].sum+t[p<<1|1].sum;
}
void spread(int p){
    if(t[p].add){
        t[p<<1].sum+=t[p].add*(t[p<<1].r-t[p<<1].l+1);
        t[p<<1|1].sum+=t[p].add*(t[p<<1|1].r-t[p<<1|1].l+1);
        t[p<<1].add+=t[p].add;
        t[p<<1|1].add+=t[p].add;
        t[p].add=0;
    }
}
void change(int p,int l,int r,int d){// 
    if(l<=t[p].l&&t[p].r<=r){
        t[p].sum+=(long long)d*(t[p].r-t[p].l+1);
        t[p].add+=d;
        return;
    }
    spread(p);
    int tm=(t[p].l+t[p].r)>>1;
    if(l<=tm)
        change(p<<1,l,r,d);
    if(r>tm)
        change(p<<1|1,l,r,d);
    t[p].sum=t[p<<1].sum+t[p<<1|1].sum;
}
long long ask(int p,int l,int r){
    if(l<=t[p].l&&t[p].r<=r)
        return t[p].sum;
    spread(p);
    int tm=(t[p].l+t[p].r)>>1;
    long long val=0;
    if(l<=tm)
        val+=ask(p<<1,l,r);
    if(r>tm)
        val+=ask(p<<1|1,l,r);
    return val; 
}
int main(){
    ios::sync_with_stdio(0);
    cin.tie(0),cout.tie(0);

    int Q,op,x,y;
    cin>>n>>Q;
    for(int i=1;i<=n;i++){
        cin>>a[i];
    }
    build(1,1,n);
    while(Q--){
        cin>>op;
        cin>>x>>y;
        if(op==1){
            cin>>d;
            change(1,x,y,d);
        }else
            cout<<ask(1,x,y)<<endl;
    }
    return 0;
}

球馆 qwq


by fang20081114 @ 2024-08-16 14:42:53

还有query返回值逻辑上有点问题,如果m不在[nl,nr]区间内应该返回0


by Laugh_at_the_sky @ 2024-08-16 14:53:33

为啥在结构体里加上

Node() {
        l = r = sum = tag = 0;
    }

就能 AC?


by cqbzpyl @ 2024-08-16 14:56:33

@Laugh_at_the_sky 不知道


by cqbzpyl @ 2024-08-16 14:57:10

@Laugh_at_the_sky 但理论上不能 AC,rp 问题


by cqbzpyl @ 2024-08-16 15:00:20

这还是我学的线段树吗


| 下一页