敌兵布阵 HDU - 1166 A Simple Problem with Integers

vj网址点击打开链接

原oj网址点击打开链接

这个题 是明显的是线段树 vj网址有中文 所以 在这里 就不多说了 代码上有我自己的见解 本人是个小菜鸡 要是有什么不对的地方 还需要各位大佬们的指教 orz 这道题 应该还是算作比较简单的 题 大家如果看不懂 可以上网上看看大牛们的大作,再来看本菜虾的博客(抛玉估计就不会有人看砖了把·~~~~~)

#include<stdio.h>
#include<iostream>
#include<string.h>
#include<algorithm>
#include<string>
#include<math.h>
using namespace std;
const int nn=50500;// 数组需要开大一点 以防万一会爆炸
int sum[nn<<2];// 这是相当于nn*4 (不知道为啥线段树的代码非要这样写)
char pp[15]; // 编译器明明就优化好了 在这样写 也不会优化时间啊~~~~
void upset(int re)
{ 
    sum[re]=sum[re<<1]+sum[re<<1|1];// 这个是区间的总和 从下往上加
}
void bulid(int l,int r,int re) //  开始建树
{
    if(l==r)            //这样建树的好处 是既可以能够输入树 
     {                        //又能将sum准确的往上转递
         scanf("%d",&sum[re]);
         return;
    }
    int mid=(l+r)>>1;
    bulid(l,mid,re<<1);
    bulid(mid+1,r,re<<1|1);
    upset(re);// 开始 传递 (递归的过程可以自己慢慢的画画 试着理解一下)
}
void update(int l,int c,int ll,int rr,int re)
{
    if(rr==ll)// 这个是在树中开始查找sum的值 然后 进行加减 
    {           
        sum[re]+=c;
        return;
    }
    //upset(re);
    int mid=(ll+rr)>>1;
    if(l>mid)
        update(l,c,mid+1,rr,re<<1|1);
    else
        update(l,c,ll,mid,re<<1);
    upset(re);//这一步是向上求 可以将结果 往上叠加(大概就是在回溯的过程中)
}
int query(int l,int r,int ll,int rr,int re)
{

    if(ll>=l&&rr<=r)
    {
        return sum[re]; //这样是开始查找区间的值 查找成功 就开始传递
    }
    int mid=(ll+rr)>>1;
       int ans=0;
    if(l<=mid)
    {
        ans+=query(l,r,ll,mid,re<<1);
    }
    if(r>mid)
    {
        ans+=query(l,r,mid+1,rr,re<<1|1);
    }
    return ans;
}
int main()
{
    int t,qw=0,tt,ll,rr;
    scanf("%d",&t);
    while(t--)
    {
        qw++;
        scanf("%d",&tt);
        bulid(1,tt,1);
        // printf("1\n");
        printf("Case %d:\n",qw);
        while(~scanf("%s",pp))
        {
            if(strcmp(pp,"End")==0)
                break;
            scanf("%d%d",&ll,&rr);
            if(pp[0]=='A')
            {
                update(ll,rr,1,tt,1);
            }
            else if(pp[0]=='S')
            {
                update(ll,-rr,1,tt,1);
            }
            else
            {
                printf("%d\n",query(ll,rr,1,tt,1));
            }
        }
    }
    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值