【模板】线段树 1

it2022-05-05  256

题目描述 如题,已知一个数列,你需要进行下面两种操作:

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的结果。

输入输出样例 输入 #1复制 5 5 1 5 4 2 3 2 2 4 1 2 3 2 2 3 4 1 1 5 1 2 1 4 输出 #1复制 11 8 20 说明/提示 时空限制:1000ms,128M

数据规模:

对于30%的数据:N<=8,M<=10

对于70%的数据:N<=1000,M<=10000

对于100%的数据:N<=100000,M<=100000

(数据已经过加强_,保证在int64/long long数据范围内)

样例说明:

#include<iostream> #include<cstdio> using namespace std; long long read(){ char ch=getchar(); long long a=0,x=1; while(ch<'0'||ch>'9'){ if(ch=='-') x=-x; ch=getchar(); } while(ch>='0'&&ch<='9'){ a=(a<<3)+(a<<1)+(ch-'0'); ch=getchar(); } return a*x; } long long n,m,k,x,y,v; long long a[100001],sum[400001],lazy[400001]; void build(long long node,long long l,long long r){ if(l==r){ sum[node]=a[l]; return ; } long long mid=(l+r)>>1; build(node*2,l,mid); build(node*2+1,mid+1,r); sum[node]=sum[node*2]+sum[node*2+1]; } void pushdown(long long node,long long l,long long r){ if(!lazy[node]){ return ; } long long mid=(l+r)>>1; lazy[node*2]+=lazy[node]; lazy[node*2+1]+=lazy[node]; sum[node*2]+=lazy[node]*(mid-l+1); sum[node*2+1]+=lazy[node]*(r-mid); lazy[node]=0; } void add(long long node,long long l,long long r,long long x,long long y,long long k) { if(x<=l&&r<=y) { sum[node]+=k*(r-l+1); lazy[node]+=k; return ; } pushdown(node,l,r); long long mid=(l+r)>>1; if(x<=mid){ add(node*2,l,mid,x,y,k); } if(y>mid){ add(node*2+1,mid+1,r,x,y,k); } sum[node]=sum[node*2]+sum[node*2+1]; } long long ask(long long node,long long l,long long r,long long x,long long y){ if(x<=l&&r<=y){ return sum[node]; } pushdown(node,l,r); long long mid=(l+r)>>1; long long rnt=0; if(x<=mid){ rnt+=ask(node*2,l,mid,x,y); } if(y>mid){ rnt+=ask(node*2+1,mid+1,r,x,y); } return rnt; } int main(){ n=read(); m=read(); for(int i=1;i<=n;i++){ a[i]=read(); } build(1,1,n); for(int i=1;i<=m;i++){ k=read(); x=read(); y=read(); if(k==1){ v=read(); add(1,1,n,x,y,v); } else{ printf("%lld\n",ask(1,1,n,x,y)); } } return 0; }

最新回复(0)