【洛谷P3372】【模板】线段树1

来源:互联网 发布:单片机 扩展功能 编辑:程序博客网 时间:2024/06/05 08:02

好像好久没打线段树了手都生了..我再来重新打份模板(好像还没A过..23333)

题目描述

    如题,已知一个数列,你需要进行下面两种操作:
    1.将某区间每一个数加上x
    2.求出某区间每一个数的和

输入输出格式

输入格式

    第一行包含两个整数N、M,分别表示该数列数字的个数和操作的总个数。
    第二行包含N个用空格分隔的整数,其中第i个数字表示数列第i项的初始值。
    接下来M行每行包含3或4个整数,表示一个操作,具体如下:
    操作1: 格式:1 x y k 含义:将区间[x,y]内每个数加上k
    操作2: 格式:2 x y 含义:输出区间[x,y]内每个数的和

输出格式

    输出包含若干行整数,即为所有操作2的结果。

输入输出样例

输入样例

5 5
1 5 4 2 3
2 2 4
1 2 3 2
2 3 4
1 1 5 1
2 1 4

输出样例

11
8
20

说明

    时空限制:1000ms,128M
    数据规模:
    对于30%的数据:N<=8,M<=10
    对于70%的数据:N<=1000,M<=10000
    对于100%的数据:N<=100000,M<=100000
    (数据已经过加强^_^,保证在int64/long long数据范围内)
    样例说明:
    这里写图片描述

思路

没啥好说的,一看到区间修改和区间求和就想到线段树就行了2333

Code

#pragma GCC optimize(3)#include<bits/stdc++.h>using namespace std;typedef long long ll;inline void readInt(int &x) {    x=0;int f=1;char ch=getchar();    while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}    while(isdigit(ch))x=x*10+ch-'0',ch=getchar();    x*=f;}inline void readLong(ll &x) {    x=0;int f=1;char ch=getchar();    while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}    while(isdigit(ch))x=x*10+ch-'0',ch=getchar();    x*=f;}/*================Header Template==============*/#define lson o<<1#define rson o<<1|1const int maxn=100010;struct seg_tree{ll l,r,sum,lazy;}t[maxn<<2];int n,m,type,l,r,x;inline void pushup(int o){t[o].sum=t[lson].sum+t[rson].sum;}inline void pushdown(int o) {    if(t[o].lazy) {        t[lson].lazy+=t[o].lazy;        t[rson].lazy+=t[o].lazy;        t[lson].sum+=t[o].lazy*(t[lson].r-t[lson].l+1);        t[rson].sum+=t[o].lazy*(t[rson].r-t[rson].l+1);        t[o].lazy=0;    }}inline void build(int o,int l,int r) {//  cout<<o<<" "<<l<<" "<<r<<endl;    t[o].l=l;    t[o].r=r;    if(l==r) {        readLong(t[o].sum);        return;    }    int mid=(l+r)>>1;//  cout<<mid<<endl;    build(lson,l,mid);    build(rson,mid+1,r);    pushup(o);}inline void update(int o,int l,int r,int ql,int qr,ll add) {    pushdown(o);    if(t[o].l==ql&&t[o].r==qr) {        t[o].lazy+=add;        t[o].sum+=add*(qr-ql+1);        return;    }    int mid=(l+r)>>1;    if(qr<=mid)        update(lson,l,mid,ql,qr,add);    else if(ql>mid)        update(rson,mid+1,r,ql,qr,add);    else {        update(lson,l,mid,ql,mid,add);        update(rson,mid+1,r,mid+1,qr,add);    }    pushup(o);}inline ll query(int o,int l,int r,int ql,int qr) {    pushdown(o);    if(l==ql&&r==qr)        return t[o].sum;    int mid=(l+r)>>1;    if(qr<=mid)        return query(lson,l,mid,ql,qr);    else if(ql>mid)        return query(rson,mid+1,r,ql,qr);    else        return query(lson,l,mid,ql,mid)+query(rson,mid+1,r,mid+1,qr);}int main() {    readInt(n);    readInt(m);    build(1,1,n);    while(m--) {        readInt(type);        if(type==1) {            readInt(l);            readInt(r);            readInt(x);            update(1,1,n,l,r,x);        }        else {            readInt(l);            readInt(r);            printf("%lld\n",query(1,1,n,l,r));        }    }    return 0;}
原创粉丝点击