#include<iostream>
#include<cstdio>
using namespace std;
/*经过多次测试,scanf怎样都比cin快。以后尽量都使用scanf&printf
*
*
* */
typedef long long ll;
const int MAX_N=100000+10;
struct nod{
int l,r;
ll delta;//5
ll sum;
}node[MAX_N<<2];
void pushup(int p){
node[p].sum=node[p<<1].sum+node[p<<1|1].sum;
}
void down(int p){
if(node[p].delta){
cout<<p<<":"<<node[p].sum<<endl;
node[p<<1].sum+=(node[p<<1].r-node[p<<1].l+1)*node[p].delta;
node[p<<1|1].sum+=(node[p<<1|1].r-node[p<<1|1].l+1)*node[p].delta;
node[p<<1].delta+=node[p].delta;//3
node[p<<1|1].delta+=node[p].delta;//4
node[p].delta=0;
}
}
void build(int p,int l,int r){
node[p].l=l;
node[p].r=r;
node[p].delta=0;//1
if(l==r){
scanf("%lld",&node[p].sum);
cout<<p<<":"<<node[p].sum<<endl;
return;
}
int mid=(l+r)>>1;
build(p<<1,l,mid);
build(p<<1|1,mid+1,r);
pushup(p);
}
void modify(int p,int a,int b,int c){
if(a<=node[p].l&&node[p].r<=b){
node[p].delta+=c;//2
node[p].sum+=c*(node[p].r-node[p].l+1);
// cout<<node[p].l<<"--"<<node[p].r<<":"<<node[p].sum<<endl;
return;
}
down(p);
int mid=(node[p].l+node[p].r)>>1;
if(a<=mid){
modify(p<<1,a,b,c);//别改变a,b
}
if(mid<b){
modify(p<<1|1,a,b,c);
}
pushup(p);
}
ll query(int p,int a,int b){
if(a<=node[p].l&&node[p].r<=b){
//cout<<p<<":"<<node[p].sum<<endl;
return node[p].sum;
}
down(p);
int mid=(node[p].l+node[p].r)>>1;
ll res=0;
if(a<=mid){
res+=query(p<<1,a,b);//千万别改变a,b
// cout<<(p<<1)<<"left:"<<res<<endl;
}
if(mid<b){
int r=query(p<<1|1,a,b);//改了a,b极有可能更改了范围,别这样
res+=r;
// cout<<(p<<1|1)<<"right:"<<r<<endl;
}
// pushup(p);
return res;
}
int main(){
//std::ios::sync_with_stdio(false);
int n,q;
int a,b,c;
char op;
scanf("%d%d",&n,&q);
build(1,1,n);
while (q--) {
getchar();
op=getchar();
if(op=='Q'){
scanf("%d%d",&a,&b);
// printf("%lld\n",query(1,a,b));
cout<<query(1,a,b)<<'\n';
}else{
scanf("%d%d%d",&a,&b,&c);
modify(1,a,b,c);
}
}
return 0;
}
线段树之区间修改(区间整数操作)
最新推荐文章于 2024-08-21 19:41:42 发布