【poj】3468 - A Simple Problem with Integers(线段树)

题目连接

给出长度为n的整数序列,给出q次操作。操作分为区间更新和区间和查询两种。

区间更新线段树裸题,算是板子题。

AC代码:

#include<stdio.h>
using namespace std;
const int N = 1e5+100;
typedef long long ll;
struct NODE{
    int l,r;    //左右端点 
    int mid(){
        return (l+r)>>1;
    }
    int add;    //lazy_tag  表示该段区间增加 add 
    ll sum;     //区间和 
}node[N<<2];

void pushup(int x){     //向上操作 
    node[x].sum = node[x<<1].sum + node[x<<1|1].sum;
}
void pushdown(int x,int m){     //向下操作 
    if(node[x].add){            //如果存在 lazy_tag 
        node[x<<1].add += node[x].add;
        node[x<<1|1].add += node[x].add;
        node[x<<1].sum += (ll)node[x].add*(m - (m>>1));
        node[x<<1|1].sum += (ll)node[x].add*(m>>1);
        node[x].add = 0;        //push完毕,清零 
    }
}
void build(int x,int l,int r){      //建树 
    node[x].l = l;
    node[x].r = r;
    node[x].add = 0;
    if(l == r){
        scanf("%lld",&node[x].sum);
        return;
    }
    int mid = node[x].mid();
    build(x<<1,l,mid);              //递归建树 
    build(x<<1|1,mid+1,r);
    pushup(x);                      //回溯求 node[x].sum 
}
inline void updata(int c,int l,int r,int x){
    if(node[x].l == l && node[x].r == r){       //区间重合 
        node[x].add += c;
        node[x].sum += (ll)c*(r-l+1);
        return;
    }
    if(node[x].l == node[x].r)  return;         //叶子节点 
    pushdown(x,node[x].r - node[x].l + 1);      //lazy_tag 下放 
    int mid = node[x].mid();
    if(r <= mid){                               //递归更新 
        updata(c,l,r,x<<1);
    }
    else if(l > mid){                           //注意没有等号 
        updata(c,l,r,x<<1|1);
    }
    else{
        updata(c,l,mid,x<<1);
        updata(c,mid+1,r,x<<1|1);
    }
    pushup(x);                                  //回溯 
}
inline ll query(int l,int r,int x){
    if(node[x].l == l && node[x].r == r){
        return node[x].sum; 
    }
    pushdown(x,node[x].r - node[x].l + 1);
    ll res = 0;
    int mid = node[x].mid();
    if(r <= mid){                               //递归查询 
        res += query(l,r,x<<1);
    }
    else if(l > mid){                           //注意没有等号
        res += query(l,r,x<<1|1);
    }
    else{
        res += query(l,mid,x<<1);
        res += query(mid+1,r,x<<1|1);
    }
    return res;
}
int main(){
    int n,q;
    char op[2];
    int a,b,c;
    scanf("%d %d",&n,&q);
    build(1,1,n);
    while(q--){
        scanf("%s",op);
        if(op[0] == 'Q'){
            scanf("%d %d",&a,&b);
            printf("%lld\n",query(a,b,1));
        }
        else{
            scanf("%d %d %d",&a,&b,&c);
            updata(c,a,b,1);
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41009682/article/details/81916929