poj 3468 A Simple Problem with Integers(線段樹+lazy)

題目大意:

        有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;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章