补补补!
单点更新
#include <iostream>
#include <cstring>
#include <string>
#include <cstdio>
using namespace std;
int t,n,inp[50010],c[50010];//inp为输入的值,c为树状数组
int lowbit(int x){//求2^k,k为二进制末尾0的个数。
return x&(-x);
}
int getsum(int x){
int sum=0;
for(int i=x;i>0;i-=lowbit(i)){
sum+=c[i];
}
return sum;
}
void Add(int pos,int num){
for(int i=pos;i<=n;i+=lowbit(i)){
c[i]+=num;
}
}
int main(){
scanf("%d",&t);
for(int p=1;p<=t;p++){
printf("Case %d:\n",p);
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&inp[i]);
Add(i,inp[i]);
}
string a;
while(cin>>a){
if(a=="End"){
break;
}
int j,k;
scanf("%d%d",&j,&k);
if(a=="Query"){
printf("%d\n",getsum(k)-getsum(j-1));
}
else if(a=="Add"){
Add(j,k);
}
else if(a=="Sub"){
Add(j,-k);
}
}
for(int i=0;i<=n;i++){
c[i]=0;
}
}return 0;
}
区间更新(差分)
#include <iostream>
#include <string>
using namespace std;
typedef long long int ll;
int n,q;
ll inp[100010],sum1[100010],sum2[100010];
int lowbit(int x){
return x&(-x);
}
void Add(int pos,ll num){
int x=pos;
for(int i=pos;i<=n;i+=lowbit(i)){
sum1[i]+=num;
sum2[i]+=num*(x-1);
}
}
ll getsum(int t){
ll sum=0;
for(int i=t;i>0;i-=lowbit(i)){
sum+=t*sum1[i]-sum2[i];
}
return sum;
}
int main(){
cin>>n>>q;
for(int i=1;i<=n;i++){
cin>>inp[i];
Add(i,inp[i]-inp[i-1]);
}
for(int i=0;i<q;i++){
string a;
ll l,r,num;
cin>>a;
if(a=="Q"){
cin>>l>>r;
cout<<getsum(r)-getsum(l-1)<<endl;
}
if(a=="C"){
cin>>l>>r>>num;
Add(l,num);
Add(r+1,-num);
}
}
return 0;
}