題目大意:
有n個數字和q個操作,操作分兩種,一種是查詢區間[a,b]的和,另一種是給區間[a,b]每個元素增加c;
解題思路:
因爲單點增加會超時,所以使用lazy的思想來減少更新次數,提高效率。
我寫的程序中的inc中的數字還沒有加到區間和sum中,這一點跟普通的lazy有一點不同,push_down和push_up的操作也直接寫在了updata和query中。
代碼:
#include <iostream>
#include <stdio.h>
using namespace std;
struct node{
int l,r;
long long sum,inc;
};
node tree[400005];
int n,q,a[100005];
void buildTree(int root,int l,int r){
tree[root].l = l;
tree[root].r = r;
tree[root].inc = 0;
if(l != r){
int mid = (l+r)/2;
buildTree(2*root,l,mid);
buildTree(2*root+1,mid+1,r);
tree[root].sum = tree[2*root].sum + tree[2*root+1].sum;
return;
}
tree[root].sum = a[l];
}
void updata(int root,int a,int b,int c){
if(tree[root].l == a && tree[root].r == b){
tree[root].inc += c;
return;
}
tree[root].sum += (b-a+1)*c;
int mid = (tree[root].l+tree[root].r)/2;
if(b <= mid){
updata(2*root,a,b,c);
}
else if(a > mid){
updata(2*root+1,a,b,c);
}
else{
updata(2*root,a,mid,c);
updata(2*root+1,mid+1,b,c);
}
}
long long query(int root,int a,int b){
if(tree[root].l == a && tree[root].r == b){
return tree[root].sum + (b-a+1)*tree[root].inc;
}
tree[2*root].inc += tree[root].inc;
tree[2*root+1].inc += tree[root].inc;
tree[root].sum += (tree[root].r-tree[root].l+1)*tree[root].inc;
tree[root].inc = 0;
int mid = (tree[root].l+tree[root].r)/2;
if(b <= mid){
return query(2*root,a,b);
}
else if(a > mid){
return query(2*root+1,a,b);
}
else{
return query(2*root,a,mid) + query(2*root+1,mid+1,b);
}
}
int main()
{
char s[10];
int x,y,z;
scanf("%d%d",&n,&q);
for(int i = 1; i <= n; i ++){
scanf("%d",&a[i]);
}
buildTree(1,1,n);
for(int i = 0; i < q; i ++){
scanf("%s",s);
if(s[0] == 'C'){
scanf("%d%d%d",&x,&y,&z);
updata(1,x,y,z);
}
else{
scanf("%d%d",&x,&y);
printf("%I64d\n",query(1,x,y));
}
}
return 0;
}