hdu 1166 第一道线段树,点更新

<a target=_blank href="http://acm.hdu.edu.cn/showproblem.php?pid=1166" target="_blank" style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">点击打开链接</a>

本题,拿到后我的第一想法是用数组进行维护,但是很遗憾,TLE 了,看了题解,研究了几天终于AC了。贴个代码纪念一下

<a target=_blank href="http://acm.hdu.edu.cn/showproblem.php?pid=1166" target="_blank"></a><pre name="code" class="cpp">#include<iostream>
#include<cstdio>
#include<algorithm>
#include<string>
#include<string.h>
#define Max 50005*4
using namespace std;
struct node{
    int rt;
    int rson;
    int lson;
    int mid()
    {
        return (rson+lson)>>1;
    }
}node[Max];
int ans;
void build(int left,int right,int r)
{
    node[r].lson=left;
    node[r].rson=right;
    if(left==right)
    {
        scanf("%d",&node[r].rt);
        return;
    }
  int mid = node[r].mid();

        build(left,mid,r<<1);
        build(mid+1,right,r<<1|1);
        node[r].rt=node[r<<1].rt+node[r<<1|1].rt;

}
void query(int left,int right,int r,int L,int R)
{
    if(L<=left&&right<=R)
    {
        ans+=node[r].rt;
        return;
    }
        int m=node[r].mid();
        if(R<=m)
            query(left,m,r<<1,L,R);
        else if(m<L)
            query(m+1,right,r<<1|1,L,R);
        else
        {
            query(left,m,r<<1,L,R);
            query(m+1,right,r<<1|1,L,R);
        }

}
void update(int left,int right,int r,int pos,int add)
{
    if(left==right)
    {
        node[r].rt+=add;
        return;
    }
    int mid = node[r].mid();
    if(pos<=mid)
        update(left,mid,r<<1,pos,add);
    else
        update(mid+1,right,r<<1|1,pos,add);
    node[r].rt=node[r<<1].rt+node[r<<1|1].rt;

}
int main()
{
    int t;
    scanf("%d",&t);
    for(int z=1;z<=t;z++)
    {
        int n;
        printf("Case %d:\n",z);
        scanf("%d",&n);
        build(1,n,1);
        char op[30];
        int a,b;
        while(scanf("%s",op))
        {
            if(op[0]=='E') break;
            scanf("%d %d",&a,&b);
            if(op[0]=='Q')
            {
                ans=0;
                query(1,n,1,a,b);
                printf("%d\n",ans);
            }
            else if(op[0]=='A')
                update(1,n,1,a,b);
            else update(1,n,1,a,-1*b);
        }
    }
    return 0;
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值