//线段树 #include<iostream> using namespace std; //注意变量的统一,当你使用long long int时,最后统一全部用long long int相加相乘,否则会出现WA long long int data[100010],ans; struct seg { long long int sum,add,l,r;//sum为改区间的总和,ADD表示该区间内增加的量 }segTree[400010]; //静态线段树的空间必须是给定区间大小的4倍,因为最坏情况是树最底层被分成1个区间点和1个空结点 void buildTree(int fa,int l,int r)//建立线段树 { segTree[fa].l = l; segTree[fa].r = r; segTree[fa].add = 0; if(l == r) segTree[fa].sum = data[l]; else { int mid = (l + r) >> 1; buildTree(2 * fa,l,mid); buildTree(2 * fa + 1,mid + 1,r); segTree[fa].sum = segTree[2*fa].sum + segTree[2*fa+1].sum;//增加左子树和右子树的和 } } void modify(int fa,int l,int r,int add)//修改区间的值 { if(segTree[fa].l == l && segTree[fa].r == r)//对完全覆盖的区间标记,表示这个区间内所有值要增加ADD { segTree[fa].add += add; return; } segTree[fa].sum += add * (r - l + 1);//如果为完全覆盖区间,则在寻找覆盖区间的过程中增加SUM值,注意与上面步骤的先后顺序 int mid = (segTree[fa].l + segTree[fa].r) >> 1; if(r <= mid) modify(2 * fa,l,r,add); else if(l > mid) modify(2 * fa + 1,l,r,add); else { modify(2 * fa,l,mid,add); modify(2 * fa + 1,mid + 1,r,add); } } void search(int fa,int l,int r,int add)//搜索区间 { add += segTree[fa].add;//随着搜索过程,记录完全覆盖区间内所需要增加的大小 if(segTree[fa].l == l && segTree[fa].r == r) { ans += segTree[fa].sum + add * (segTree[fa].r - segTree[fa].l + 1);//找到目标区间,增加ANS return; } int mid = (segTree[fa].l + segTree[fa].r) >> 1; if(r <= mid) search(2 * fa,l,r,add); else if(l > mid) search(2 * fa + 1,l,r,add); else { search(2 * fa,l,mid,add); search(2 * fa + 1,mid + 1,r,add); } } int main() { //freopen("in.txt","r",stdin); int n,m,a,b,add; char command; scanf("%d%d",&n,&m); for(int i = 1;i <= n;++i) scanf("%I64d",&data[i]); buildTree(1,1,n); for(int i = 1;i <= m;++i) { scanf("/n");//清除缓冲区,读取单个字符串时 scanf("%c",&command); if(command == 'C') { scanf("%d%d%d",&a,&b,&add); modify(1,a,b,add); } else { ans = 0; scanf("%d%d",&a,&b); search(1,a,b,0); printf("%I64d/n",ans); } } return 0; }