在discuss里面看到有用树状数组做的,于是找了个做法http://kenby.iteye.com/blog/962159
貌似和我线段树的时间差不多,都是1600ms 左右,但是人家就可以进1秒,大概是我代码写挫了吧
#include<iostream>
#include<cstring>
#include<cstdio>
#define lowbit(x) ((x)&(-x))
using namespace std;
typedef long long LL;
const int MAXN = 100020;
LL delta[MAXN]; //The delta Array with its prefix sum
LL delta1[MAXN]; //The delta[i]*i Array
LL c[MAXN];
int n,m;
#define M(a) memset(a,0,sizeof(a))
bool init()
{
int num;
if(scanf("%d%d",&n,&m)==EOF)return false;
M(c);M(delta);M(delta1);
return true;
}
void __add(LL *c,int pos,int num)
{
while(pos<=n)
{
c[pos]+=num;
pos+=lowbit(pos);
}
}
LL __sum(LL *c,int pos)
{
LL res =0;
while(pos >0)
{
res += c[pos];
pos -= lowbit(pos);
}
return res;
}
void ADD()
{
int x,y,num;
scanf("%d%d%d",&x,&y,&num);++y;
__add(delta,x,num);
__add(delta,y,-num);
__add(delta1,x,x*num);
__add(delta1,y,y*(-num));
}
LL sum[MAXN];
void Query()
{
int x,y;
scanf("%d%d",&x,&y);x--;
LL res = sum[y]-sum[x];
res += (y+1)*__sum(delta,y) - __sum(delta1,y);
res -= (x+1)*__sum(delta,x) - __sum(delta1,x);
cout<<res<<endl;
}
void solve()
{
int num;
sum[0]=0;
for(int i=1;i<=n;i++)
{
scanf("%d",&num);
sum[i]=sum[i-1]+num;
__add(c,i,num);
}
char cmd[10];
while(m--)
{
scanf("%s",cmd);
switch(cmd[0])
{
case 'Q':Query();break;
case 'C':ADD();break;
default :cout<<"fuck"<<endl;
}
}
}
int main()
{
freopen("3468.txt","r",stdin);
while(init())
solve();
return 0;
}