poj 3468 A Simple Problem with Integers

点击打开链接poj 3468


思路:线段树成段更新
分析:
1 最基础的线段树的成段更新的题目,我们只要建好线段树然后进行更新即可
2 注意由于输入的数最大为10^9,因此我们应该使用long long,区间的和已经区间的延时标记都要为long long

代码:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;

typedef long long int64;
const int MAXN = 100010;
struct Node{
    int left;
    int right;
    int64 mark;
    int64 sum;
};
Node node[4*MAXN];
int64 num[MAXN];
int N , Q;

//向上更新
void push_up(int pos){
    node[pos].sum = node[pos<<1].sum + node[(pos<<1)+1].sum;
}

//向下更新
void push_down(int pos){
    if(node[pos].mark){
       node[pos<<1].mark += node[pos].mark;
       node[(pos<<1)+1].mark += node[pos].mark;
       node[pos<<1].sum += node[pos].mark*(node[pos<<1].right-node[pos<<1].left+1); 
       node[(pos<<1)+1].sum += node[pos].mark*(node[(pos<<1)+1].right-node[(pos<<1)+1].left+1);
       node[pos].mark = 0;
    }
}

//建立线段树
void buildTree(int left , int right , int pos){
    node[pos].left = left;
    node[pos].right = right;
    node[pos].mark = 0;
    if(left == right){
        node[pos].sum = num[left];
        node[pos].mark = num[left];
        return;
    }
    int mid = (left+right)>>1;
    buildTree(left , mid , pos<<1);
    buildTree(mid+1 , right , (pos<<1)+1);
    push_up(pos);//向上更新
}

//成段更新
void update(int left , int right , int value , int pos){
    if(left <= node[pos].left && right >= node[pos].right){
      node[pos].mark += value;
      node[pos].sum += value*(node[pos].right-node[pos].left+1);
      return ;
    }
    push_down(pos);
    int mid = (node[pos].left+node[pos].right)>>1;
    if(right <= mid)
        update(left , right , value , pos<<1);
    else if(left > mid)
        update(left , right , value , (pos<<1)+1);
    else{
        update(left , mid , value , pos<<1);
        update(mid+1 , right , value , (pos<<1)+1);
    }
    push_up(pos);
}

int64 query(int left , int right , int pos){
    if(node[pos].left == left && node[pos].right == right)
        return node[pos].sum;
    int mid = (node[pos].left+node[pos].right)>>1;
    push_down(pos);//继续向下更新,才能完全更新完毕
    if(right <= mid)
        return query(left , right , pos<<1);
    else if(left > mid)
        return query(left , right , (pos<<1)+1);
    else
        return query(left , mid , pos<<1) + query(mid+1 , right , (pos<<1)+1);
}

int main(){
    char str[MAXN] , ch;
    int x , y , d;
    while(scanf("%d%d" , &N , &Q) != EOF){
       for(int i = 1 ; i <= N ; i++)
          scanf("%lld" , &num[i]);
       gets(str);
       buildTree(1 , N , 1);
       for(int i = 0 ; i < Q ; i++){
          gets(str);
          if(str[0] == 'Q'){
             sscanf(str , "%c %d %d" , &ch , &x , &y);
             printf("%lld\n" , query(x , y , 1));
          }
          else{ 
             sscanf(str , "%c %d %d %d" , &ch , &x , &y , &d);
             update(x , y , d , 1);
          }
       }
    }
    return 0;
}



你可能感兴趣的:(poj 3468 A Simple Problem with Integers)