【模板】线段树

今天考试的时候很开心的打了一个线段树,考完一看,SMG

#include<iostream> 
#include<cstring>
#include<cstdio>
#include<algorithm>
#define maxn 100001
#define LL long long 
using namespace std;
struct node
{LL l,r,sum;}tree[maxn*3];
LL a[maxn],f[maxn],lazy[maxn*3];
inline LL read()
{
    char ch=getchar();
    LL f=1,x=0;
    while(!(ch>='0'&&ch<='9')) { if(ch=='-') f=-1;ch=getchar();}
    while((ch>='0'&&ch<='9')) {x=x*10+(ch-'0');ch=getchar();}
    return f*x;
}
void build(LL x,LL l,LL r)
{
    tree[x].l=l;tree[x].r=r;
    if(l==r){tree[x].sum=read();return;}
    build(x*2,l,(l+r)>>1);
    build(x*2+1,1+((l+r)>>1),r);
    tree[x].sum=tree[x*2+1].sum+tree[x*2].sum;
}
void pushdown(LL x)
{
    LL mid=(tree[x].l+tree[x].r)/2;
    tree[x*2].sum+=(mid-tree[x].l+1)*lazy[x];
    tree[x*2+1].sum+=(tree[x].r-mid)*lazy[x];
    lazy[x*2]+=lazy[x];
    lazy[x*2+1]+=lazy[x];
    lazy[x]=0;
}
void update(LL x,LL l,LL r,LL k)
{
    if(tree[x].l>=l&&tree[x].r<=r)
    {
        tree[x].sum+=(tree[x].r-tree[x].l+1)*k;
        lazy[x]+=k;
        return;
    }
    if(tree[x].l>r||tree[x].r<l) return;
    LL mid=(tree[x].r+tree[x].l)>>1;
    if(lazy[x]) pushdown(x);
    update(x*2,l,r,k);update(x*2+1,l,r,k);
    tree[x].sum=tree[x*2].sum+tree[x*2+1].sum;
}
LL query(LL x,LL l,LL r)
{
    if(tree[x].l>=l&&tree[x].r<=r) return tree[x].sum;
    if(tree[x].l>r||tree[x].r<l) return 0;
    if(lazy[x]) pushdown(x);
    return query(x*2,l,r)+query(2*x+1,l,r);
}
int main()
{
   LL n,m,x,y,z;
   n=read();m=read();
   build(1,1,n);
   for(LL i=1;i<=m;i++)
   {
        z=read();x=read();y=read();
        if(z==1) {z=read();update(1,x,y,z);}
        else cout<<query(1,x,y)<<endl;
   }
   return 0; 
}
View Code
原文地址:https://www.cnblogs.com/LQ-double/p/6069585.html