#include <iostream>#include<stdio.h>using namespace std;const int maxn=100002;int sum[maxn*4]={0};//这个要初始化为0int col[maxn*4]={0};//标记每个节点,初始化为0//将子节点的数据传到根节点void PushUp(int rt){//存放节点的总和 sum[rt]=sum[rt*2]+sum[rt*2+1];}//将m个值做标记void PushDownAdd(int rt,int m){ //如果该点做了标记 if(col[rt]) { //那么为该点的孩子节点也做标记col[rt*2]+=col[rt];col[rt*2+1]+=col[rt]; //并修改该点孩子节点的值 sum[rt*2]+=(m-m/2)*col[rt]; sum[rt*2+1]+=(m/2)*col[rt]; col[rt]=0;//取消该点的标记 }}//将m个值做标记void PushDownValue(int rt,int m){ //如果该点做了标记 if(col[rt]) { //那么为该点的孩子节点也做标记 col[rt*2]=col[rt*2+1]=col[rt]; //并修改该点孩子节点的值 sum[rt*2]=(m-m/2)*col[rt]; sum[rt*2+1]=(m/2)*col[rt]; col[rt]=0;//取消该点的标记 }}//递归创建树,并且更新到根节点,sum保存了这个线段的值void build(int l,int r,int rt){ if(l==r) {cin>>sum[rt]; return; } int m=(l+r)/2; build(l,m,rt*2); build(m+1,r,rt*2+1); PushUp(rt);}//在l到r区间中查找left到right区间的和int query(int left,int right,int l,int r,int rt){ if(l==left && r==right) { return sum[rt]; }PushDownAdd(rt,r-l+1); int mid=(r+l)/2; int ret=0; if(right<=mid)//在左孩子{ ret+=query(left,right,l,mid,rt*2);} else if(left>=mid+1)//在右孩子 ret+=query(left,right,mid+1,r,rt*2+1); else//一半在左孩子一半在右孩子 { //先查找left到mid区间的和,在计算mid+1到right区间的和 ret+=query(left,mid,l,mid,rt*2); ret+=query(mid+1,right,mid+1,r,rt*2+1); } return ret;}//在l到r区间中更新left到right区间的值加上add,并且更新它父亲的值void updateAdd(int left,int right,int add,int l,int r,int rt){ //要更新的这个区间在l到r区间内 if(left<=l && r<=right) {//只在该点做修改,其他点就不在修改,只是做标记 col[rt]+=add;//在该点做标记---标记累加 sum[rt]+=add*(r-l+1);//该点的值做修改 return; } //修改该点的孩子的值 PushDownAdd(rt,r-l+1); int m=(l+r)/2; if(left<=m) updateAdd(left,right,add,l,m,rt*2); if(right>m) updateAdd(left,right,add,m+1,r,rt*2+1); PushUp(rt);//更改rt节点的总和}//在l到r区间中更新left到right区间的值为add,并且更新它父亲的值void updateValue(int left,int right,int value,int l,int r,int rt){ //要更新的这个区间在l到r区间内 if(left<=l && r<=right) {//只在该点做修改,其他点就不在修改,只是做标记 col[rt]=value;//在该点做标记 sum[rt]=value*(r-l+1);//该点的值做修改 return; } //修改该点的孩子的值 PushDownValue(rt,r-l+1); int m=(l+r)/2; if(left<=m) updateValue(left,right,value,l,m,rt*2); if(right>m) updateValue(left,right,value,m+1,r,rt*2+1); PushUp(rt);//更改rt节点的总和}int main(){int N,Q; char ch; int a,b;int c; scanf("%d%d",&N,&Q);build(1,N,1); while(Q--) {cin>>ch; if(ch=='Q') { scanf("%d%d",&a,&b); printf("%d\n",query(a,b,1,N,1)); } else if(ch=='C') { scanf("%d%d%d",&a,&b,&c); updateAdd(a,b,c,1,N,1); } } return 0;}