树状数组模板
0x00 前言
(我说我在快睡着的情况下写了个这你信吗
0x01 区间查询
#include<bits/stdc++.h>
#define int long long//跟同机房大佬学到的,懒到无可救药时可以写写,考试时千万别
using namespace std;
const int N=5000100;
int n,m;
int tree[N];
int read(){
int x=0,y=1;
char c=getchar();
while(c<'0'||c>'9'){
if(c=='-')
y=-1;
c=getchar();
}
while(c>='0'&&c<='9'){
x=x*10+c-'0';
c=getchar();
}
return x*y;
}
int lowbit(int x){
return x&-x;
}
void add(int x,int y){
while(x<=n){
tree[x]+=y;
x+=lowbit(x);
}
}
int sum(int x){
int ans=0;
while(x!=0){
ans+=tree[x];
x-=lowbit(x);
}
return ans;
}
signed main(){
n=read();
m=read();
for(int i=1;i<=n;i++){
int a;
a=read();
add(i,a);
}
for(int i=1;i<=m;i++){
int a,b,c;
a=read();
b=read();
c=read();
if(a==1)
add(b,c);
else
printf("%d\n",sum(c)-sum(b-1));
}
return 0;
}
这也是\(P3374\)的正解
0x02 单点查询
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=10000010;
ll n,m,q,x,y,k;
ll sig[N],tree[N];
ll read(){
ll x=0,y=1;
char c=getchar();
while(c<'0'||c>'9'){
if(c=='-')
y=-1;
c=getchar();
}
while(c>='0'&&c<='9'){
x=x*10+c-'0';
c=getchar();
}
return x*y;
}
ll lowbit(ll num){
return num&-num;
}
void add(ll k,ll num){
for(ll i=k;i<=n;i+=lowbit(i))
tree[i]+=num;
}
ll ask(ll k){
ll ans=0;
for(ll i=k;i>=1;i-=lowbit(i))
ans+=tree[i];
return ans;
}
int main(){
n=read();
m=read();
for(int i=1;i<=n;i++)
sig[i]=read();
for(int i=1;i<=m;i++){
q=read();
if(q==1){
x=read();
y=read();
k=read();
add(x,k);
add(y+1,-k);
}
if(q==2){
x=read();
printf("%lld\n",sig[x]+ask(x));
}
}
return 0;
}
这也是\(P3368\)的正解