之前这道题用树状数组水过的,但是用线段树一直wa或者tle,昨天终于AC了。。贴一下,binsec结构可当模版.
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int M=131072;
template<class T>
struct binsec
{
T data[M+M];
T sum[M+M];
int L[M+M],R[M+M];
bool def[M+M];
binsec(int l0,int r0)
{
L[1]=l0;R[1]=r0;
for(int i=1;i<M;i++){
L[i<<1]=L[i];
R[i<<1]=(R[i]+L[i])>>1;
L[(i<<1)+1]=((R[i]+L[i])>>1)+1;
R[(i<<1)+1]=R[i];
}
memset(data,0,sizeof(data));
memset(def,0,sizeof(def));
memset(sum,0,sizeof(sum));
}
void _inc(int l,int r,int t,T v)
{
def[t]=true;
sum[t]+=(r-l+1)*v;
if(L[t]==l&&R[t]==r)data[t]+=v;
else
{
int t2=(t<<1);
if(l>=L[t2+1])_inc(l,r,t2+1,v);
else if(r<=R[t2])_inc(l,r,t2,v);
else{
_inc(l,R[t2],t2,v);
_inc(L[t2+1],r,t2+1,v);
}
}
}
T _tot(int l,int r,int t)
{
if(l==L[t]&&r==R[t])return sum[t];
int t2=(t<<1);
T res=(r-l+1)*data[t];
if(l>=L[t2+1]){
if(def[t2+1])res+=_tot(l,r,t2+1);
}
else if(r<=R[t2]){
if(def[t2])res+=_tot(l,r,t2);
}
else{
if(def[t2])res+=_tot(l,R[t2],t2);
if(def[t2+1])res+=_tot(L[t2+1],r,t2+1);
}
return res;
}
};
long long data[100100];
binsec<__int64> s(1,M);
int main()
{
int n,q,l,r;
__int64 v;
scanf("%d%d",&n,&q);
for(int i=1;i<=n;i++)
scanf("%I64d",&(data[i]));
for(int i=2;i<=n;i++)
data[i]+=data[i-1];
char c;
for(int i=0;i<q;i++){
getchar();
scanf("%c%d%d",&c,&l,&r);
if(l>r)swap(l,r);
if(l<1)l=1;
if(r>n)r=n;
if(c=='Q')
{
printf("%I64d\n",s._tot(l,r,1)+data[r]-data[l-1]);
}
else
{
scanf("%I64d",&v);
s._inc(l,r,1,v);
}
}
}