线段树--数列操作

假设有一列数 {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) ,表示操作数 v 下接 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<stdio.h>
using namespace std;
const int maxn=100010;
struct node
{
        int a,b,sum;
        int lc,rc;
} tree[maxn*2];
int a[maxn];
int tail,n,m,Sum;
void modify(int now,int left,int right,int st)
{
        int a1=tree[now].a,b1=tree[now].b;
        if (left==a1 && b1==right)
         {
                 tree[now].sum=tree[now].sum+st;
                return ;
         }
        int lcl=tree[now].lc,rcl=tree[now].rc;
        int mid=(a1+b1)>>1;
        if (right<=mid)
         {
                 modify(lcl,left,right,st);
                 tree[now].sum=tree[tree[now].lc].sum+tree[tree[now].rc].sum;
         }
        else if (left>=mid)
         {
                 modify(rcl,left,right,st);
                 tree[now].sum=tree[tree[now].lc].sum+tree[tree[now].rc].sum;
         }
        else
         {
                 modify(lcl,left,mid,st);
                 modify(rcl,mid,right,st);
                 tree[now].sum=tree[tree[now].lc].sum+tree[tree[now].rc].sum;
         }
}
void getsum(int now,int left,int right)
{
        int a1=tree[now].a,b1=tree[now].b;
        if (left==a1 && b1==right)
         {
                 Sum+=tree[now].sum;
                return ;
         }
        int lcl=tree[now].lc,rcl=tree[now].rc;
        int mid=(a1+b1)>>1;
        if (right<=mid) getsum(lcl,left,right);
        else if (left>=mid) getsum(rcl,left,right);
        else
         {
                 getsum(lcl,left,mid);
                 getsum(rcl,mid,right);
         }
}
void make_tree(int a1,int b1)
{
         tail++;int now=tail;
         tree[now].a=a1;tree[now].b=b1;
         tree[now].sum=0;
         tree[now].lc=tree[now].rc=-1;
        if (a1+1<b1)
         {
                int mid=(a1+b1)>>1;
                 tree[now].lc=tail+1;   make_tree(a1,mid);
                 tree[now].rc=tail+1;   make_tree(mid,b1);
                 tree[now].sum=tree[tree[now].lc].sum+tree[tree[now].rc].sum;
         }
        else if (a1+1==b1) tree[now].sum=a[b1];
}
int main()
{
         freopen("shulie.in","r",stdin);
         freopen("shulie.out","w",stdout);
         scanf("%d",&n);
        for (int i=1;i<=n;i++) scanf("%d",&a[i]);
        tail=0;
         make_tree(0,n);
         scanf("%d",&m);
        char ss[10]={0};int s,t;
        for (int i=1;i<=m;i++)
         {
                 getchar();
                 scanf("%s %d%d",ss,&s,&t);
                if (!strcmp(ss,"SUM"))
                 {
                         Sum=0;
                         getsum(1,s-1,t);
                         printf("%d/n",Sum);
                 }
                else modify(1,s-1,s,t);
         }
        return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值