题目描述

给定一个长度为N的数列A,以及M条指令,每条指令可能是以下两种之一:

1、“C l r d”,表示把 A[l],A[l+1],…,A[r] 都加上 d。

2、“Q l r”,表示询问 数列中第 l~r 个数的和。

对于每个询问,输出一个整数表示答案。

输入格式

第一行两个整数N,M。

第二行N个整数A[i]。

接下来M行表示M条指令,每条指令的格式如题目描述所示。

输出格式

对于每个询问,输出一个整数表示答案。

每个答案占一行。

数据范围

1≤N,M≤10^5,
|d|≤10000|,
|A[i]|≤1000000000|

样例

输入样例: 10 5 1 2 3 4 5 6 7 8 9 10 Q 4 4 Q 1 10 Q 2 4 C 3 6 3 Q 2 4 输出样例: 4 55 9 15


AC代码:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
#include<stdlib.h>
#include<queue>
#include<map>
#include<iomanip>
#include<math.h>
using namespace std;
typedef long long ll;
typedef double ld;
#define lowbit(x) x&(-x)
const int N=2e5+10;
ll c1[N],c2[N],n,m,a[N];
ll add(ll x,ll y)
{
for(ll i=x;i<=n;i+=lowbit(i))
{
c1[i]+=y;
c2[i]+=x*y;
}
}
ll ask(ll x)
{
ll ans=0;
for(ll i=x;i;i-=lowbit(i))
ans+=(x+1) *c1[i]-c2[i];
return ans;
}
int main()
{
scanf("%lld %lld\n",&n,&m);
for(ll i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
add(i,a[i]);
add(i+1,-a[i]);
}
getchar();
while(m--)
{
char ch=getchar();
if (ch=='Q')
{
ll x,y;
scanf("%lld %lld\n",&x,&y);
cout<<ask(y)-ask(x-1)<<endl;
}
if (ch=='C')
{
ll x,y,d;
scanf("%lld %lld %lld\n",&x,&y,&d);
add(x,d);
add(y+1,-d);
}
}
return 0;
}

另一种写法:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
#include<stdlib.h>
#include<queue>
#include<map>
#include<iomanip>
#include<math.h>
using namespace std;
typedef long long ll;
typedef double ld;
#define lowbit(x) x&(-x)
const int N=2e5+10;
ll c1[N],c2[N],n,m,q,i,a[N];
ll sum[N];


void add(ll x,ll d,ll *c)
{
for(;x<=n;x+=lowbit(x))
{
c[x]+=d;
}
}

ll ask(ll x,ll *c)
{
ll sum=0;
for(;x>0;x-=lowbit(x))
{
sum+=c[x];
}
return sum;
}

int main()
{
char op[3];
ll x,y,d;
scanf("%lld %lld",&n,&q);
memset(c1,0,sizeof c1);
memset(c2,0,sizeof c2);
for(i=1; i<=n; ++i)
{
scanf("%lld",sum+i);
sum[i]+=sum[i-1];
}
while(q--)
{
scanf("%s",op);
if(op[0] == 'C')
{
scanf("%lld%lld%lld",&x,&y,&d);
add(x,d,c1);
add(y+1,-d,c1);
add(x,x*d,c2);
add(y+1,-(y+1)*d,c2);
}
else
{
scanf("%lld %lld",&x,&y);
printf("%lld\n",sum[y]-sum[x-1]+ask(y,c1)*(y+1)-ask(x-1,c1)*x-ask(y,c2)+ask(x-1,c2));
}
}
return 0;
}