题意:线段树段修改的板子题
思路:套板子,注意mark _down和值都要用longlong
#include <cstdio>
#include<iostream>
typedef long long ll;
using namespace std;
const int maxn=100000*5+100;
struct segn
{
ll su,mark_add;
}segt[maxn];
void push_dowm_segadd(int root,int st,int en)
{
if(segt[root].mark_add!=0)
{
segt[root*2+1].su+=((st+en)/2-st+1)*segt[root].mark_add;
segt[root*2+2].su+=(en-(st+en)/2)*segt[root].mark_add;
segt[root*2+1].mark_add+=segt[root].mark_add;
segt[root*2+2].mark_add+=segt[root].mark_add;
segt[root].mark_add=0;
}
}
void build(ll *arr,int root,int st,int en)
{
if(st==en)
{
segt[root].mark_add=0;
segt[root].su=arr[st];
return;
}
int mid=(st+en)/2;
build(arr,root*2+1,st,mid);
build(arr,root*2+2,mid+1,en);
segt[root].su=segt[root*2+1].su+segt[root*2+2].su;
}
void segadd(int qst,int qen,int tst,int ten,int root,ll addnum)
{
if(qst>ten||qen<tst)//不符合的区间
{
return ;
}
if(tst>=qst&&ten<=qen)//找到要加的区间
{
segt[root].mark_add+=addnum;
segt[root].su+=addnum*(ten-tst+1);
return ;
}
int mid =(tst+ten)/2;
push_dowm_segadd(root,tst,ten);
segadd(qst,qen,tst,mid,root*2+1,addnum);
segadd(qst,qen,mid+1,ten,root*2+2,addnum);
if(tst!=ten)segt[root].su=segt[root*2+1].su+segt[root*2+2].su;
}
ll query(int root,int qst,int qen,int tst,int ten)
{
if(segt[root].mark_add!=0&&tst!=ten)push_dowm_segadd(root,tst,ten);
if(qst>ten||qen<tst)return 0;
if(qst<=tst&&qen>=ten)return segt[root].su;
ll mm= query(2*root+1,qst,qen,tst,(tst+ten)/2)+query(2*root+2,qst,qen,(tst+ten)/2+1,ten);
if(tst!=ten)segt[root].su=segt[root*2+1].su+segt[root*2+2].su;
return mm;
}
int main()
{
int n,qn;
ll arr[100100];
while(~scanf("%d%d",&n,&qn))
{
for(int i=0;i<n;i++)
{
// scanf("%d",&arr[i]);
cin>>arr[i];
}
build(arr,0,0,n-1);
char gr[3];
int st,en;ll num;
while(qn--)
{
scanf("%s",gr);
if(gr[0]=='C')
{
cin>>st>>en>>num;
segadd(st-1,en-1,0,n-1,0,num);
}
else if(gr[0]=='Q')
{
scanf("%d%d",&st,&en);
cout<<query(0,st-1,en-1,0,n-1)<<endl;
} //for(int i=0;i<2*n;i++)cout<<segt[i].su<<" ";cout<<endl;
}
}
}