TLE求调

P3372 【模板】线段树 1

bzdss @ 2024-12-29 16:01:13

#include<bits/stdc++.h>
using namespace std;
long long ans[400004],num[100001],k[400004];
long long n,m;
long long left(long long a){
    return a*2;
}
long long right(long long a){
    return a*2+1;
}
void addd(long long l, long long r, long long nl, long long nr,long long p,long long kk){
    if(l<=nl and r>=nr){
        k[p]+=kk;
        ans[p]+=kk+kk*(nr-nl);
        return;
    }
    if(nl==nr){
        return; 
    }
    addd(l,r,nl,(nl+nr)/2,left(p),kk);
    addd(l,r,((nl+nr)/2)+1,nr,right(p),kk);
    return;
}
void jianzao(long long l,long long r,long long anss){
    //cout<<l<<' '<<r<<' '<<anss<<endl; 
    k[anss]=0;
    if(r==l){
        ans[anss]=num[r];
        return;
    }
    else{
        jianzao(l,(l+r)/2,left(anss));
        jianzao(((l+r)/2)+1,r,right(anss)) ;
        ans[anss]=ans[left(anss)]+ans[right(anss)];
        return;
    } 

}
long long find(long long l, long long r, long long nl, long long nr,long long p) {
    //cout<<nl<<' '<<nr<<' '<<p<<endl; 
    if(l<=nl and r>=nr)return ans[p]; 
    if(nl==nr){
        return 0; 
    }
    k[left(p)]+=k[p];
    k[right(p)]+=k[p];
    ans[left(p)]+=k[p]+k[p]*(((nl+nr)/2)-nl);
    ans[right(p)]+=k[p]+k[p]*(nr-(((nl+nr)/2)+1));
    long long sum=0;
    sum+=find(l,r,nl,(nl+nr)/2,left(p));
    sum+=find(l,r,((nl+nr)/2)+1,nr,right(p));
    return sum;
}
int main(){
    cin>>n>>m;
    for(long long i=1;i<=n;i++){
        cin>>num[i];
    }
    jianzao(1,n,1);
    while(m--){
        long long b,x,y,kk;
        cin>>b;
        if(b==1){
            cin>>x>>y>>kk;
            addd(x,y,1,n,1,kk);
        }
        else{
            cin>>x>>y;
            cout<<find(x,y,1,n,1)<<endl;
        }
    }
}

by dalu @ 2025-01-08 18:26:14

@bzdss

#include <iostream>
#include <cstring>
#include <vector>
#define int long long
using namespace std;

class Segment_tree{
private:
    std::vector < int > tree,tag,a;
public:
    void init(std::vector < int > v,int n){
        a = v;
        tree.resize((n << 2) + 5);
        tag.resize((n << 2) + 5);
    }
private:
    int ls(int p){return p << 1;}

    int rs(int p){return p << 1 | 1;}

    void push_up(int p){
        tree[p] = tree[ls(p)] + tree[rs(p)];//区间和
        //tree[p] = min(tree[ls(p)],tree[rs(p)]);//最小值
        //tree[p] = max(tree[ls(p)],tree[rs(p)]);//最大值
    }
public:
    void bulid(int p,int pl,int pr){
        tag[p] = 0;
        if(pl == pr){tree[p] = a[pl];return;}
        int mid = (pl + pr) >> 1;
        bulid(ls(p),pl,mid);
        bulid(rs(p),mid + 1,pr);
        push_up(p);
    }
private:
    void addtag(int p,int pl,int pr,int d){
        tag[p] += d;
        tree[p] += d * (pr - pl + 1);
    }

    void push_down(int p,int pl,int pr){
        if(tag[p]){
            int mid = (pl + pr) >> 1;
            addtag(ls(p),pl,mid,tag[p]);
            addtag(rs(p),mid + 1,pr,tag[p]);
            tag[p] = 0;
        }
    }
public:
    void update(int L,int R,int p,int pl,int pr,int d){
        if(L <= pl && pr <= R){
            addtag(p,pl,pr,d);
            return;
        }
        push_down(p,pl,pr);
        int mid = (pl + pr) >> 1;
        if(L <= mid) update(L,R,ls(p),pl,mid,d);
        if(R > mid) update(L,R,rs(p),mid + 1,pr,d);
        push_up(p);
    }

    int query(int L,int R,int p,int pl,int pr){
        if(pl >= L && R >= pr) return tree[p];
        push_down(p,pl,pr);
        int res = 0;
        int mid = (pl + pr) >> 1;
        if(L <= mid) res += query(L,R,ls(p),pl,mid);
        if(R > mid) res += query(L,R,rs(p),mid + 1,pr);
        return res;
    }
};

vector < int > a(100005);

signed main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr),cout.tie(nullptr);
    int n,m;
    cin >> n >> m;
    for(int i = 1;i <= n;i++) cin >> a[i];
    Segment_tree tree;
    tree.init(a,100000);
    tree.bulid(1,1,n);
    while(m--){
        int q,L,R,d;
        cin >> q;
        if(q == 1){
            cin >> L >> R >> d;
            tree.update(L,R,1,1,n,d);
        }else{
            cin >> L >> R;
            cout << tree.query(L,R,1,1,n) << '\n';
        }
    }
    return 0;
}

|