HDU 1166 敌兵布阵(线段树)

敌兵布阵

这是一个线段树的模板题,涉及到加减两种操作。

正好借这个题说一下遇到的集中奇葩情况。

线段树的知识可以自己百度下;

补充一点,后面那个输字符串和数字(eg Query 1 3)这里,不要把scanf写在if的前面,否则会出现Runtime Error错误,至今没弄明白为什么,希望后来者指点,谢谢。

先上代码:

#include<iostream>
#include<cstdio>
using namespace std;
typedef long long LL;
const int maxn = 50005;
LL val[maxn],ans;
struct Tree
{
    int l,r;
    int sum;
}tr[maxn<<2];

void build(int rt,int l,int r)
{
    tr[rt].l = l;
    tr[rt].r = r;
    if(l==r)
        tr[rt].sum=val[l];
    else
    {
        int mid = (l+r)>>1;
        build(rt<<1,l,mid);
        build(rt<<1|1,mid+1,r);
        tr[rt].sum = tr[rt<<1].sum+tr[rt<<1|1].sum;
    }
}

void update(int rt,int x,int y)
{
    tr[rt].sum+=y;
    //添加停止条件
    if(tr[rt].l==x&&tr[rt].r==x)
        return ;
    int mid=(tr[rt].l+tr[rt].r)>>1;
    if(x>mid)
        update(rt<<1|1,x,y);
    else
        update(rt<<1,x,y);
}

void query(int rt,int x,int y)
{
    if(x<=tr[rt].l&&y>=tr[rt].r)
        ans+=tr[rt].sum;
    else
    {
        int mid = (tr[rt].l+tr[rt].r)>>1;
        if(x>mid) //这个地方用的是存粹的>
            query(rt<<1|1,x,y);
        else if(y<=mid)
            query(rt<<1,x,y);
        else
        {
            query(rt<<1|1,x,y);
            query(rt<<1,x,y);
        }
    }
}

int main()
{
   LL T,F;
   F=0;
   cin>>T;
   int x,y;
   while(T--)
   {
       int N;
       cin>>N;
       for(int i=1;i<=N;i++)
            scanf("%lld",&val[i]);
       build(1,1,N);
       string s;
       while(cin>>s)
       {
           if(s=="End")
                break;
           else if(s=="Query")
           {
               scanf("%d%d",&x,&y);
               ans = 0;
               query(1,x,y);
               printf("%lld\n",ans);
           }
           else if(s=="Add")
           {
               scanf("%d%d",&x,&y);
               update(1,x,y);
           }
           else if(s=="Sub")
           {
               scanf("%d%d",&x,&y);
               update(1,x,-y);
           }
       }
   }
   return 0;
}

 

奇葩情况分析:

1,到输字符串的时候,一个字符串也没输进去:

这是因为建树(build)时,这个else少了,自己思考为什么。

2.不进行更新操作(update)的能输进去,进行更新操作的输不进去:

这是因为在更新操作(update)中,没有及时终止程序的条件,不中止岂不是要死循环去了:

3.数据都能输进去,但是结果不正确,这是因为在查询操作(query)中,执行向右建树的判断条件多了个等于;

几个口诀吧:向右建树只大于,向左建树小于等于;

结果不对。

原因,看图吧:

4.这个问题放个图片理解下吧:

5.这个问题不严重,可能时粗心问题导致的,一定要细心,特别是写代码,就是别忘了建树,不然后面的 更新 、查询 从何谈起。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值