题意:一道经典题,区间更新,区间查询。
解法:原来用的是线段树。后来学了树状数组的做法,感觉很神奇,贴上解法网址:http://www.docin.com/p-97026988.html?qq-pf-to=pcqq.c2c
代码:
/****************************************************
* author:xiefubao
*******************************************************/
#pragma comment(linker, "/STACK:102400000,102400000")
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <queue>
#include <vector>
#include <algorithm>
#include <cmath>
#include <map>
#include <set>
#include <stack>
#include <string.h>
using namespace std;
typedef long long LL;
LL C[100100];
LL B[100100];
LL tool=0;
int lowbit(int x){return x&(-x);}
int N,Q;
void updateC(int x,LL t)
{
tool+=t;
while(x<=N){
C[x]+=t;
x+=lowbit(x);
}
}
void updateB(int x,LL t)
{
while(x<=N){
B[x]+=t;
x+=lowbit(x);
}
}
LL queryC(int x)
{
LL ans=0;
while(x){
ans+=C[x];x-=lowbit(x);
}
return ans;
}
LL queryB(int x)
{
LL ans=0;
while(x){
ans+=B[x];x-=lowbit(x);
}
return ans;
}
void make(int a,int b,LL c)
{
if(a>1)updateC(a-1,-c),updateB(a-1,-c*(a-1));
updateC(b,c);
updateB(b,c*b);
}
LL query(int x)
{
LL ans=(tool-queryC(x))*x+queryB(x);
return ans;
}
int main()
{
cin>>N>>Q;
for(int i=1;i<=N;i++)
{
int a;scanf("%d",&a);make(i,i,a);
}
for(int i=0;i<Q;i++)
{
char c;getchar();scanf("%c",&c);
if(c=='Q')
{
int a,b;scanf("%d%d",&a,&b);//cout<<a<<" "<<b<<endl;
printf("%I64d\n",query(b)-query(a-1));
}
else
{
int a,b,c;scanf("%d%d%d",&a,&b,&c);
make(a,b,c);
}
}
return 0;
}