第一次写线段树啊,当模板用的以后。。。
#include<iostream>
using namespace std;
struct node{
node *pleft,*pright;
int L,R;
long long lnc;
long long nsum;
};
node tree[1000000];
int ncount=0;
int mid(node *p)
{
return (p->L+p->R)/2;
}
void buildtree(node *p,int a,int b)
{
p->L=a;
p->R=b;
p->lnc=0;
p->nsum=0;
if(a==b) return ;
ncount++;
p->pleft=ncount+tree;
ncount++;
p->pright=ncount+tree;
buildtree(p->pleft,a,(a+b)/2);
buildtree(p->pright,(a+b)/2+1,b);
}
void insert(node *p,int i,int a)
{
if(p->L==i && p->R==i)
{
p->nsum=a;
return ;
}
p->nsum+=a;
if(i<=mid(p))
insert(p->pleft,i,a);
else
insert(p->pright,i,a);
}
void add(node *p,int a,int b,long long c)
{
if(p->L==a && p->R==b){
p->lnc+=c;
return ;
}
p->nsum+=(b-a+1)*c;
if(a>=mid(p)+1)
add(p->pright,a,b,c);
else if(b<=mid(p))
add(p->pleft,a,b,c);
else
{
add(p->pleft,a,mid(p),c);
add(p->pright,mid(p)+1,b,c);
}
}
long long quiry(node *p,int a,int b)
{
if(p->L==a && p->R==b){
return p->nsum+(p->R-p->L+1)*p->lnc;
}
p->nsum+=(p->R-p->L+1)*p->lnc;
add(p->pleft,p->L,mid(p),p->lnc);
add(p->pright,mid(p)+1,p->R,p->lnc);
p->lnc=0;
if(b<=mid(p))
return quiry(p->pleft,a,b);
else if(a>=mid(p)+1)
return quiry(p->pright,a,b);
else{
return quiry(p->pleft,a,mid(p))+quiry(p->pright,mid(p)+1,b);
}
}
int main()
{
int i,j,k;
int n,q;
char ch[10];
int a,b,c;
scanf("%d%d",&n,&q);
ncount=0;
buildtree(tree,1,n);
for(i=1;i<=n;i++)
{
scanf("%d",&a);
insert(tree,i,a);
}
for(i=0;i<q;i++){
scanf("%s",ch);
if(ch[0]=='C'){
scanf("%d%d%d",&a,&b,&c);
add(tree,a,b,c);
}
else{
scanf("%d%d",&a,&b);
printf("%I64d\n",quiry(tree,a,b));
}
}
return 0;
}