南阳oj 116 士兵杀敌二 线段树

来源:互联网 发布:淘宝群词荟萃 编辑:程序博客网 时间:2024/05/22 02:31
/*此题是线段树的区间求和查询,已经线段树的单点跟新。线段树不是很懂的同学可以看这个里面有非常详细的讲解。怎么建立线段树,怎么做线段树,相信大家看了一定可以做出这个题加油~~~~~~http://blog.csdn.net/lw277232240/article/details/77092634*/#include<stdio.h>#include<string.h>#include<stdlib.h>using namespace std;#define MAX 1000000*4+10int sum[MAX];int add[MAX];int n,m;void PushUp(int rt){    sum[rt]=sum[rt*2]+sum[rt*2+1];}void build(int rt,int left,int right){    add[rt]=0;    if(left==right)    {        scanf("%d",&sum[rt]);    }    else    {        build(rt*2,left,(left+right)/2);        build(rt*2+1,(left+right)/2+1,right);        PushUp(rt);    }}void PushDown(int rt,int m){    if(add[rt])    {   add[rt*2]+=add[rt];        add[rt*2+1]+=add[rt];        sum[rt*2]+=add[rt]*(m-(m>>1));        sum[rt*2+1]+=add[rt]*(m>>1);        add[rt]=0;    }}int query(int rt,int left,int right,int l,int r){    if(left>=l&&right<=r)    {        return sum[rt];    }    PushDown(rt,right-left+1);    int mid=(left+right)/2;    int rat=0;    if(l<=mid) rat+=query(rt*2,left,mid,l,r);    if(r>mid) rat+=query(rt*2+1,mid+1,right,l,r);    return rat;}void update(int rt,int left,int right,int l,int r,int c){    if(left>=l&&right<=r)    {        sum[rt]+=c*(right-left+1);        add[rt]+=c;        return ;    }    PushDown(rt,right-left+1);    int mid=(right+left)/2;    if(l<=mid) update(rt*2,left,mid,l,r,c);    if(r>mid) update(rt*2+1,mid+1,right,l,r,c);    PushUp(rt);}int main(){    scanf("%d%d",&n,&m);    build(1,1,n);    char a[10];    int x,y;    for(int i=1;i<=m;i++)    {        scanf("%s",a);        scanf("%d%d",&x,&y);        if(a[0]=='Q')        {            printf("%d\n",query(1,1,n,x,y));        }        else        {            update(1,1,n,x,x,y);        }    }}

原创粉丝点击