poj 3468 A Simple Problem with Integers(线段树的区间更新与求和)

来源:互联网 发布:福建游龙网络 编辑:程序博客网 时间:2024/05/16 11:32
A Simple Problem with Integers

题目连接:http://poj.org/problem?id=3468

题目大意:给出一个数组,要求对一个区间所有的值加某一个数或者计算某一区间所有值的和。

题目思路:利用线段树处理,具体见代码

代码如下:

#include<iostream>#include<cstring>#include<cstdio>using namespace std;#define N 100010struct Node{    int L;    int R;    long long add;///表示左右结点的区间都要增加add    long long sum;///该节点在更新之前的值}tree[4*N];///建树void BuildTree(int root,int l,int r){    tree[root].L=l;    tree[root].R=r;    tree[root].add=0;    tree[root].sum=0;    if(l==r){        int a;        scanf("%d",&a);        tree[root].sum=a;///根节点的sum就为本身        return ;    }    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;///父节点的sum等于两子节点的和}///区间更新void Update(int root,int s,int e,long long v){    if(tree[root].L==s&&tree[root].R==e){        tree[root].add+=v;///因为区间的数每个都要加v,所有直接令add+v。。此时子节点还未更新        return ;    }    tree[root].sum+=v*(e-s+1);///区间不匹配,不能每个都加,则将要加的数总和直接赋给sum    int mid=(tree[root].L+tree[root].R)/2;    if(e<=mid) Update(2*root,s,e,v);    else if(s>mid) Update(2*root+1,s,e,v);    else {        Update(2*root,s,mid,v);        Update(2*root+1,mid+1,e,v);    }}///区间求和long long QuerySum(int root,int s,int e){    if(tree[root].L==s&&tree[root].R==e){        return tree[root].sum+(e-s+1)*tree[root].add;///区间匹配,结果为结点本身的sum加上区间还有每个数都要加的add    }    int mid=(tree[root].L+tree[root].R)/2;    ///更新子节点    tree[root].sum+=(tree[root].R-tree[root].L+1)*tree[root].add;    Update(2*root,tree[root].L,mid,tree[root].add);    Update(2*root+1,mid+1,tree[root].R,tree[root].add);    tree[root].add=0;    if(e<=mid) return QuerySum(2*root,s,e);    else if(s>mid)  return QuerySum(2*root+1,s,e);    else {        return QuerySum(2*root,s,mid)+QuerySum(2*root+1,mid+1,e);    }}int main(){    int n,q;    scanf("%d%d",&n,&q);    BuildTree(1,1,n);    while(q--){        char s[4];        scanf("%s",s);        if(s[0]=='Q'){            int a,b;            scanf("%d%d",&a,&b);            printf("%I64d\n",QuerySum(1,a,b));        }        else{            int a,b;            long long c;            scanf("%d%d%I64d",&a,&b,&c);            Update(1,a,b,c);        }    }    return 0;}


0 0
原创粉丝点击