题目描述
如题,已知一个数列,你需要进行下面两种操作:
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的结果。
输入输出样例
说明
时空限制: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; struct tree{ int l,r; long long sum,add; }t[200010]; int n,m; long long a[100010]; void read (int &A); void readl (long long &A); inline int ls (int A); inline int rs (int A); inline int mid (int L,int R); void build (int l,int r,int p); void change (int l,int r,int p,long long v); void spread (int p); long long ask (int l,int r,int p); int main(){ int x,y,ch; long long k; cin>>n>>m; for(int i=1;i<=n;i++) cin>>a[i]; build(1,n,1); for(int i=1;i<=m;i++){ cin>>ch; if(ch==1){ cin>>x>>y>>k; change(x,y,1,k); }else{ cin>>x>>y; cout<<ask(x,y,1)<<endl; } } return 0; } void read(int &A){ int FL=1;char CH=getchar();A=0; while(CH<'0'||CH>'9'){if(CH=='-');} while(CH>='0'&&CH<='9'){A=A*10+CH-'0';CH=getchar();} A*=FL; } void readl(long long &A){ int FL=1;char CH=getchar();A=0; while(CH<'0'||CH>'9'){if(CH=='-');} while(CH>='0'&&CH<='9'){A=A*10+CH-'0';CH=getchar();} A*=FL; } inline int ls(int A){return A<<1;} inline int rs(int A){return (A<<1)+1;} inline int mid(int L,int R){return L+R>>1;} void build(int l,int r,int p){ t[p].l=l; t[p].r=r; if(l==r) {t[p].sum=a[t[p].l]; return;} build(l,mid(l,r),ls(p)); build(mid(l,r)+1,r,rs(p)); t[p].sum=t[ls(p)].sum+t[rs(p)].sum; // push_up(p); } void change(int l,int r,int p,long long v){ if(l<=t[p].l && r>=t[p].r){ t[p].sum+=(t[p].r-t[p].l+1)*v; t[p].add+=v; return; } spread(p); if(l<=mid(t[p].l,t[p].r)) change(l,r,ls(p),v); if(r>mid(t[p].l,t[p].r)) change(l,r,rs(p),v); t[p].sum=t[ls(p)].sum+t[rs(p)].sum; } void spread(int p){ if(t[p].add){ t[ls(p)].sum+=t[p].add*(t[ls(p)].r-t[ls(p)].l+1); t[rs(p)].sum+=t[p].add*(t[rs(p)].r-t[rs(p)].l+1); t[ls(p)].add+=t[p].add; t[rs(p)].add+=t[p].add; t[p].add=0; } } long long ask(int l,int r,int p){ if(l<=t[p].l && r>=t[p].r) return t[p].sum; spread(p); long long val=0; if(l<=mid(t[p].l,t[p].r)) val+=ask(l,r,ls(p)); if(r>mid(t[p].l,t[p].r)) val+=ask(l,r,rs(p)); return val; }