ACM 264. 数列操作(线段树)

来源:互联网 发布:淘宝咋评价 编辑:程序博客网 时间:2024/05/17 07:06

264. 数列操作

★☆   输入文件:shulie.in   输出文件:shulie.out   简单对比
时间限制:1 s   内存限制:160 MB

【问题描述】

 假设有一列数 {Ai }(1 ≤ i ≤ n) ,支持如下两种操作:

(1)将 A k 的值加 D 。( k, D 是输入的数)

(2) 输出 A s +A s+1 +…+A t 。( s, t 都是输入的数, S ≤ T )

根据操作要求进行正确操作并输出结果。

【输入格式】

     输入文件第一行一个整数 n(0<=n<=100000) , 第二行为 n 个整数,表示 {A i } 的初始值。

第三行为一个整数 m(0<=m<=150000) ,表示操作数。 下接 m 行,每行描述一个操作,有如下两种情况:

ADD k d ( 表示将 A k 加 d , 1<=k<=n , d 为整数 )

SUM s t (表示输出 A s +…+A t )

【输出格式】

    对于每一个 SUM 提问,输出结果

【输入输出样例】
 
输入:

4
1 4 2 3 
3
SUM 1 3 
ADD 2 50
SUM 2 3

输出:

7
56


#include <iostream>#include <cstring>#include <cstdio>using namespace std;#define MAX_N 100000int n;int num[MAX_N];struct Node{    int Sum;    int Delay;    Node *pLeft,*pRight;};void Init(Node **pNode,int Left,int Right){    Node *pNew=new Node;    if(Right-Left==1)    {        pNew->Delay=0;        pNew->Sum=num[Left];        pNew->pLeft=pNew->pRight=NULL;    }    else    {        int mid=(Right+Left)>>1;        pNew->Sum=0;        pNew->Delay=0;        Init(&pNew->pLeft,Left,mid);        Init(&pNew->pRight,mid,Right);        pNew->Sum=pNew->pLeft->Sum+pNew->pRight->Sum;    }    *pNode=pNew;}void Add(Node *pNode,int ID,int val,int Left,int Right){    if(Right-Left==1)    {        pNode->Sum+=val;    }    else    {        int mid=(Left+Right)>>1;        if(ID<mid)        {            Add(pNode->pLeft,ID,val,Left,mid);        }        else        {            Add(pNode->pRight,ID,val,mid,Right);        }        pNode->Sum=pNode->pLeft->Sum+pNode->pRight->Sum;    }}void Add(Node *pNode,int a,int b,int val,int Left,int Right){    if(a<=Left && Right>=b)    {        pNode->Sum+=val*(Right-Left);        pNode->Delay+=val;    }    else    {        int mid=(Right+Left)>>1;        if(pNode->Delay)        {            pNode->pLeft->Sum+=pNode->Delay*(mid-Left);            pNode->pLeft->Delay+=pNode->Delay;            pNode->pRight->Sum+=pNode->Delay*(Right-mid);            pNode->pRight->Delay+=pNode->Delay;            pNode->Delay=0;        }        if(a<mid)            Add(pNode->pLeft,a,b,val,Left,mid);        if(b>mid)            Add(pNode->pRight,a,b,val,mid,Right);        pNode->Sum=pNode->pLeft->Sum+pNode->pRight->Sum;    }}int Sum(Node *pNode,int a,int b,int Left,int Right){    if(a<=Left && Right<=b)    {        return pNode->Sum;    }    else    {        int s1=0,s2=0;        int mid=(Left+Right)>>1;        if(a<mid)            s1=Sum(pNode->pLeft,a,b,Left,mid);        if(b>mid)            s2=Sum(pNode->pRight,a,b,mid,Right);        return s1+s2;    }}int Sum2(Node *pNode,int a,int b,int Left,int Right){    if(a<=Left && Right<=b)    {        return pNode->Sum;    }    else    {        int s1=0,s2=0;        int mid=(Left+Right)>>1;        if(pNode->Delay)        {            pNode->pLeft->Sum+=pNode->Delay*(mid-Left);            pNode->pLeft->Delay+=pNode->Delay;            pNode->pRight->Sum+=pNode->Delay*(Right-mid);            pNode->pRight->Delay+=pNode->Delay;            pNode->Delay=0;        }        if(a<mid)            s1=Sum2(pNode->pLeft,a,b,Left,mid);        if(b>mid)            s2=Sum2(pNode->pRight,a,b,mid,Right);        return s1+s2;    }}int main(){    freopen("shulie.in","r",stdin);    freopen("shulie.out","w",stdout);    Node *pNode;    scanf("%d",&n);    for(int i=0;i<n;i++) scanf("%d",&num[i]);    if(n==0) return 0;    Init(&pNode,0,n);    int m;    scanf("%d",&m);    char words[8];    for(int i=0;i<m;i++)    {        int a,b;        scanf("%s%d%d",words,&a,&b);        if(!strcmp(words,"SUM"))        {            printf("%d\n",Sum(pNode,a-1,b,0,n));        }        else        {            Add(pNode,a-1,b,0,n);        }    }    return 0;}


0 0
原创粉丝点击