A Simple Problem with Integers
Crawling in process...
Crawling failed
Time Limit:5000MS Memory Limit:131072KB 64bit IO Format:%I64d & %I64u
Description
给出了一个序列,你需要处理如下两种询问。
"C a b c"表示给[a, b]区间中的值全部增加c (-10000 ≤ c ≤ 10000)。
"Q a b" 询问[a, b]区间中所有值的和。
Input
第一行包含两个整数N, Q。1 ≤ N,Q ≤ 100000.
第二行包含n个整数,表示初始的序列A (-1000000000 ≤ Ai ≤ 1000000000)。
接下来Q行询问,格式如题目描述。
Output
对于每一个Q开头的询问,你需要输出相应的答案,每个答案一行。
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
区间更新,不往下的时候不用pushdown,标记要为正,且可叠加。
#include"cstdio"
#include"cstring"
#include"iostream"
#include"algorithm"
using namespace std;
#define MAX 100005
#define LL long long
#define lson id*2
#define rson id*2+1
LL N;
LL a[MAX];
LL ans;
struct TREE
{
LL l,r,sum,mark;
}tree[MAX*4];
void pushup(LL id)
{
tree[id].sum = tree[lson].sum + tree[rson].sum;
}
void pushdown(LL id)
{
tree[lson].mark += tree[id].mark;
tree[rson].mark += tree[id].mark;
//之前先将父亲结点的标记取消了再将标记下移,这样会导致重复计算
tree[lson].sum += tree[id].mark * (tree[lson].r - tree[lson].l + 1);
tree[rson].sum += tree[id].mark * (tree[rson].r - tree[rson].l + 1);
tree[id].mark = 0;
}
void build(LL id,LL l,LL r)
{
tree[id].l = l;
tree[id].r = r;
tree[id].mark = 0;
if(l == r)
{
tree[id].sum = a[l];
}
else
{
LL mid = (l+r)/2;
build(lson,l,mid);
build(rson,mid+1,r);
pushup(id);
}
}
void update(LL id,LL l,LL r,LL val)
{
if(tree[id].l > r || tree[id].r < l)
{
return ;
}
if(tree[id].l >= l && tree[id].r <= r)
{
tree[id].mark += val;
tree[id].sum += (tree[id].r - tree[id].l + 1)*val;
return ;
}
if(tree[id].mark)
{
pushdown(id);
}
update(lson,l,r,val);
update(rson,l,r,val);
pushup(id);
}
void query(LL id,LL l,LL r)
{
if(tree[id].r < l || tree[id].l > r)
{
return ;
}
if(tree[id].l >= l && tree[id].r <= r)
{
ans += tree[id].sum;
return ;
}
if(tree[id].mark)
{
pushdown(id);
}
int mid = (tree[id].l+tree[id].r)/2;
if(r <= mid) query(lson,l,r); //lson为l ~ mid
else if(l > mid) query(rson,l,r); //rson为mid+1 ~ r
else
{
query(lson,l,mid);
query(rson,mid+1,r);
}
}
int main()
{
LL Q;
while(~scanf("%lld%lld",&N,&Q))
{
for(LL i = 1;i <= N;i++)
{
scanf("%lld",&a[i]);
}
build(1,1,N);
char s[3];
LL p,q,m;
while(Q--)
{
scanf("%s",s);
if(s[0] == 'Q')
{
scanf("%lld%lld",&p,&q);
ans = 0;
query(1,p,q);
printf("%lld\n",ans);
}
else
{
scanf("%lld%lld%lld",&p,&q,&m);
update(1,p,q,m);
}
}
}
return 0;
}