hdu 1166(线段树&&树状数组)

基础题,用线段树和树状数组各写了一遍,线段树莫名tle和re....tle改了个数组大小就没事了?!然后开始wr,又改了个结构,意思没变,就A了。。。excuse me?

/*树状数组*/
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn=50000+100;
int aa[maxn];
int n,t;
int low(int x)
{
    return x&-x;
}
void add(int x,int val)
{
    for(int i=x;i<=n;i+=low(i))
       aa[i]+=val;
}
int sum(int a,int b)
{
    int he=0,ha=0;
    for(int i=b;i>0;i-=low(i))
        he+=aa[i];
     for(int i=a-1;i>0;i-=low(i))
        ha+=aa[i];
    return he-ha;
}
int main()
{
    scanf("%d",&t);
    for(int zz=1;zz<=t;zz++)
    {
        memset(aa,0,sizeof(aa));
        scanf("%d",&n);
        int md;
       for(int i=1;i<=n;i++)
       {
           scanf("%d",&md);
           add(i,md);
       }

      printf("Case %d:\n",zz);
       while(1)
       { string ss;
         cin >> ss;
         int a,b;
         if(ss[0]=='E') break;
         else if(ss[0]=='A')
         {
             scanf("%d%d",&a,&b);
             add(a,b);
         }
          else if(ss[0]=='S')
         {
             scanf("%d%d",&a,&b);
             b=-b;
             add(a,b);
         }
         else if(ss[0]=='Q')
         {
              scanf("%d%d",&a,&b);
               int mm=sum(a,b);
               printf("%d\n",mm);
         }

       }
    }
    return 0;
}
/*线段树*/
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn=50000+100;
int a[maxn];
const int inf=0x3f3f3f3f;
int t,n;
struct setree
{
    int val;
}tree[maxn*3];
void build(int root,int a[],int l,int r)
{
    if(l==r)
    {
        tree[root].val=a[l];
        return;
    }
    int mid=(l+r)/2;
   build(root*2,a,l,mid);
   build(root*2+1,a,mid+1,r);
   tree[root].val=tree[root*2].val+tree[root*2+1].val;
}
void upone(int root,int l,int r,int v,int vval)
{
    if(l==r)
    {
        if(l==v)
         tree[root].val+=vval;
         return;
    }
    int mid=(l+r)/2;
   if(v<=mid)
    upone(root*2,l,mid,v,vval);
    else
     upone(root*2+1,mid+1,r,v,vval);
    tree[root].val=tree[root*2].val+tree[root*2+1].val;
}
int serch(int root,int l,int r,int a,int b)
{
    if(b<l||a>r) return 0;
    if(a<=l&&b>=r) return tree[root].val;
    int mid=(l+r)/2;
    int mm=serch(root*2,l,mid,a,b);
    int nn=serch(root*2+1,mid+1,r,a,b);
   return mm+nn;
}
int main()
{
   scanf("%d",&t);
   for(int zz=1;zz<=t;zz++)
  {
      scanf("%d",&n);
        for(int i=1;i<=n;i++)
         scanf("%d",&a[i]);
       build(1,a,1,n);
       printf("Case %d:\n",zz);
      while(1)
      {
          int a,b;
          char hh[20];
           scanf("%s",hh);
          if(hh[0]=='E') break;
          else if(hh[0]=='A')
          {
            scanf("%d%d",&a,&b);
             upone(1,1,n,a,b);
          }
          else if(hh[0]=='S')
          {
               scanf("%d%d",&a,&b);
               b=-b;
             upone(1,1,n,a,b);
          }
          else if(hh[0]=='Q')
          {
              scanf("%d%d",&a,&b);
               int mmp=serch(1,1,n,a,b);
               printf("%d\n",mmp);
          }
      }
  }
    return 0;
}

 

转载于:https://www.cnblogs.com/Wangwanxiang/p/7264650.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值