单点更新 区间查询

敌兵布阵 

坑点:cin cout 一直超时  改成 scanf 和printf  就过了

/*输入
t样例
N(N<=50000) 
第i个正整数ai代表第i个工兵营地里开始时有ai个人(1<=ai<=50)。

接下来每行有一条命令,命令有4种形式:
(1) Add i j,i和j为正整数,表示第i个营地增加j个人(j不超过30)
(2)Sub i j ,i和j为正整数,表示第i个营地减少j个人(j不超过30);
(3)Query i j ,i和j为正整数,i<=j,表示询问第i到第j个营地的总人数;
(4)End 表示结束,这条命令在每组数据最后出现;

1
10
1 2 3 4 5 6 7 8 9 10
Query 1 3
Add 3 6
Query 2 7
Sub 10 2
Add 6 3
Query 3 10
End  


输出
Case 1:
6
33
59
*/

#include <string.h>
#include <stdio.h>
using namespace std;
int n,t[50005];
int lowbit(int x)
{
     return x&(-x);
}

void update(int x,int val)//单点更新
{
    while(x<=n){
        
        t[x]+=val;
        x+=lowbit(x);//由叶子节点向上更新树状数组C,从左往右更新
    }
}

int ask(int x)//求区间[1,i]内所有元素的和 即求前缀和
{
    int ans=0;
    while(x>0){
        ans+=t[x];//从右往左累加求和
        x-=lowbit(x);
    }
    return ans;
}

int main()
{
    int tt,cnt=0,b,c,i,a;
    char s[10];
    scanf("%d",&tt);
    while(tt--)
    {
        scanf("%d",&n);
        memset(t,0,sizeof(t));
        for(i=1;i<=n;i++)
        {
            scanf("%d",&a);
            update(i,a);
        }
         printf("Case %d:\n",++cnt);
        while(scanf("%s",s))
        {
             if(s[0]=='E') break;
             scanf("%d%d",&c,&b);
             if(s[0]=='S') update(c,-b);
            
            if(s[0]=='A') update(c,b);
            
            if(s[0]=='Q') 
            {
                printf("%d\n",ask(b)-ask(c-1)); 
            }               
        }
    }
    return 0;
} 
View Code

相关文章:

  • 2022-12-23
  • 2022-12-23
  • 2021-08-30
  • 2021-09-11
  • 2021-09-16
  • 2022-12-23
  • 2021-12-30
  • 2021-11-09
猜你喜欢
  • 2021-09-17
  • 2021-06-03
  • 2021-06-07
  • 2022-01-28
  • 2022-12-23
  • 2021-12-21
  • 2021-12-06
相关资源
相似解决方案