经典RMQ问题
解决方案: 树状数组,或者线段树
只要是能用树状数组解决的,肯定都能用线段树解决。
这里先写用树状数组解决的,然后再写用线段树的。
树状数组代码: 核心代码就是lowbit,以及常用的求和和更新操作。
int lowbit(int x){
return x&(-x);
}
int sum(int n){
int ans=0;
while(n!=0){
ans+=c[n];
n-=lowbit(n);
}
return ans;
}
void change(int i,int x){
while(i<=n){
c[i]+=x;
i+=lowbit(i);
}
}
树状AC代码:
#include <iostream>
#include<cstdio>
#include<cstring>
#include<string>
using namespace std;
const int maxn=50005;
int a[maxn];
int c[maxn];
int T;
int n;
int lowbit(int x){
return x&(-x);
}
int sum(int n){
int ans=0;
while(n!=0){
ans+=c[n];
n-=lowbit(n);
}
return ans;
}
void change(int i,int x){
while(i<=n){
c[i]+=x;
i+=lowbit(i);
}
}
int main()
{
string command;
int x,y;
int sum1=0;
int sum2=0;
scanf("%d",&T);
int cnt=1;
while(T--){
scanf("%d",&n);
memset(c,0,sizeof(c));
a[0]=0;
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
}
// build binary indexed tree
for(int i=1;i<=n;i++){
if(i%2==1)c[i]=a[i];
else{
int k=lowbit(i);
for(int j=i-k+1;j<=i;j++){
c[i]+=a[j];
}
}
}
printf("Case %d:\n",cnt);
//input command
while(true){
cin>>command;
if(command=="End") break;
scanf("%d%d",&x,&y);
if(command=="Query"){
sum1=sum(x-1);
sum2=sum(y);
printf("%d\n",sum2-sum1);
}else if(command=="Add"){
change(x,y);
}else if(command=="Sub"){
change(x,-y);
}
}
cnt++;
}
return 0;
}