【重码数据结构】线段树1

背景:今天心血来潮要重新码线段树。

   但是。

   突然发现真是一条不归路。

   这出错那出错

   整了半天,发现两个小错误。

下面说说为什么重码。

之前写的在结构体中存了一个节点的L和R。

就比较费空间。

再加上码风难看抄的题解,根本不可读。

所以重新写一遍。

代码如下(有lazy标记)。

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=100001;
struct tree{
    ll add,sum;
}t[maxn<<2];
ll a[maxn];
int n,m;
void build(int p,int l,int r){
    if(l==r){
        t[p].sum=a[l];return;
    }
    int mid=(l+r)>>1;
    build(p<<1,l,mid);
    build(p<<1|1,mid+1,r);
    t[p].sum=t[p<<1|1].sum+t[p<<1].sum;
}
inline void pushdown(int p,int l,int r){
    if(!t[p].add) return;
    int mid=(l+r)>>1;
    t[p<<1].sum+=t[p].add*(mid-l+1);
    t[p<<1|1].sum+=t[p].add*(r-mid);
    t[p<<1].add+=t[p].add;
    t[p<<1|1].add+=t[p].add;
    t[p].add=0;
}
inline void ad(int p,int l,int r,int x,int y,int d){
    if(x<=l && y>=r){
        t[p].add+=d;
        t[p].sum+=(ll)d*(r-l+1);
        return;
    }
    pushdown(p,l,r);
    int mid=(l+r)>>1;
    if(x<=mid) ad(p<<1,l,mid,x,y,d);
    if(y>mid) ad(p<<1|1,mid+1,r,x,y,d);
    t[p].sum=t[p<<1].sum+t[p<<1|1].sum;
}
inline ll ask(int p,int l,int r,int x,int y){
    if(x<=l && y>=r){
        return t[p].sum;
    }
    pushdown(p,l,r);
    ll ans=0;
    int mid=(l+r)>>1;
    if(x<=mid) ans+=ask(p<<1,l,mid,x,y);
    if(y>mid) ans+=ask(p<<1|1,mid+1,r,x,y);
    return ans;
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
        scanf("%lld",&a[i]);
    build(1,1,n);
    while(m--){
        int c;
        scanf("%d",&c);
        if(c==1){
            int x,y;
            ll k;
            scanf("%d%d%lld",&x,&y,&k);
            ad(1,1,n,x,y,k);
        }
        else{
            int x,y;
            scanf("%d%d",&x,&y);
            printf("%lld\n",ask(1,1,n,x,y));
        }
    }
    // system("pause");
    return 0;
}

例题就是线段树1,luogu_P3372:https://www.luogu.org/problemnew/show/P3372

 

posted @ 2019-06-10 22:46  ChrisKKK  阅读(170)  评论(0编辑  收藏  举报