题目:
You have N integers, A1, A2, … , AN. You need to deal with two kinds of operations. One type of operation is to add some given number to each number in a given interval. The other is to ask for the sum of numbers in a given interval.
Input
The first line contains two numbers N and Q. 1 ≤ N,Q ≤ 100000.
The second line contains N numbers, the initial values of A1, A2, … , AN. -1000000000 ≤ Ai ≤ 1000000000.
Each of the next Q lines represents an operation.
“C a b c” means adding c to each of Aa, Aa+1, … , Ab. -10000 ≤ c ≤ 10000.
“Q a b” means querying the sum of Aa, Aa+1, … , Ab.
Output
You need to answer all Q commands in order. One answer in a line.
Sample Input
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
Sample Output
4
55
9
15
Hint
The sums may exceed the range of 32-bit integers.
题意:
给你一个序列,要你进行区间修改以及区间查询.
ps:
模板题,lazy标记的使用,没啥说的,注意lazy是累加,还有sum更新的方法是加上区间长乘以更新值,还有一个地方坑了我好久找bug,写在代码注释里了。
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define ls (rt<<1)
#define rs (rt<<1|1)
#define lson L,mid,ls
#define rson mid+1,R,rs
#define def_mid int mid=(L+R)>>1
#define ll long long
#define INF 0x3f3f3f3f
using namespace std;
const int maxn = 123456;
ll sum[maxn<<2],lazy[maxn<<2];
ll a[maxn];
void pushup(int rt)
{
sum[rt]=sum[ls]+sum[rs];
}
void pushlazy(int lz,int len,int rt)
{
sum[rt]+=(ll)lz*len;//被这里坑了两个int类型相乘会爆int所以在这里要强转为ll
lazy[rt]+=lz;
}
void pushdown(int L,int R,int rt)
{
if(lazy[rt]!=0)
{
def_mid;
pushlazy(lazy[rt],mid-L+1,ls);
pushlazy(lazy[rt],R-mid,rs);
lazy[rt]=0;
}
return;
}
void build(int L,int R,int rt)
{
lazy[rt]=0;
if(L==R)
{
sum[rt]=a[L];
return;
}
def_mid;
build(lson);
build(rson);
pushup(rt);
}
void update(int l,int r,int L,int R,int rt,int k)
{
if(l<=L&&r>=R)
{
sum[rt]+=k*(R-L+1);
lazy[rt]+=k;
return;
}
pushdown(L,R,rt);
def_mid;
if(l<=mid)
update(l,r,lson,k);
if(r>mid)
update(l,r,rson,k);
pushup(rt);
}
ll querysum(int l,int r,int L,int R,int rt)
{
if(l<=L&&r>=R)
return sum[rt];
pushdown(L,R,rt);
def_mid;
ll ret=0;
if(l<=mid)
ret+=querysum(l,r,lson);
if(r>mid)
ret+=querysum(l,r,rson);
return ret;
}
int main()
{
int n,q,k;
while(scanf("%d%d",&n,&q)!=EOF)
{
memset(lazy,0,sizeof(lazy));
memset(sum,0,sizeof(sum));
memset(a,0,sizeof(a));
char op[3];
int l,r;
for(int i=1;i<=n;i++)
scanf("%lld",&a[i]);
build(1,n,1);
while(q--)
{
scanf("%s%d%d",op,&l,&r);
if(op[0]=='Q')
printf("%lld\n",querysum(l,r,1,n,1));
else
{
scanf("%d",&k);
update(l,r,1,n,1,k);
}
}
}
return 0;
}