树状数组模版
2025-08-04 11:14:06
发布于:浙江
3阅读
0回复
0点赞
题目描述
如题,已知一个数列,你需要进行下面两种操作:
将某一个数加上 x
求出某区间每一个数的和
输入格式
第一行包含两个正整数 n,m,分别表示该数列数字的个数和操作的总个数。
第二行包含 n 个用空格分隔的整数,其中第 i 个数字表示数列第 i 项的初始值。
接下来 m 行每行包含 3 个整数,表示一个操作,具体如下:
1 x k 含义:将第 x 个数加上k
2 x y 含义:输出区间 [x,y] 内每个数的和
输出格式
输出包含若干行整数,即为所有操作 2 的结果。
#include<bits/stdc++.h>
using namespace std;
const int N=5*1e5+100;
int n,m;
int Num[N],pre[N];
int lowbit(int i){
return i&-i;
}
void add(int i,int j){
while(i<=n){
pre[i]+=j;
i+=lowbit(i);
}
}
int query(int i){
int ans=0;
while(i>0){
ans+=pre[i];
i-=lowbit(i);
}
return ans;
}
int main(){
cin>>n>>m;
for(int i=1;i<=n;++i){
cin>>Num[i];
add(i,Num[i]);
}
while(m--){
int a,b,c;
cin>>a>>b>>c;
if(a==1){
add(b,c);
}
else{
cout<<query(c)-query(b-1)<<endl;
}
}
}
全部评论 1
逆序对-树状数组版
#include<bits/stdc++.h> using namespace std; const int N=5*1e5+100; int n; int Num[N],Tool[N],pre[N]; int lowbit(int i){ return i&-i; } void add(int i,int j){ while(i<=n){ pre[i]+=j; i+=lowbit(i); } } int ask(int i){ int ans=0; while(i>0){ ans+=pre[i]; i-=lowbit(i); } return ans; } int main(){ cin>>n; //离散化 set <int> s; map <int,int> mp; for(int i=1;i<=n;++i){ cin>>Num[i]; s.insert(Num[i]); } int num=0; for(auto x:s){ mp[x]=++num; } for(int i=1;i<=n;++i){ Tool[i]=mp[Num[i]]; } //离散化结束 long long ans=0; for(int i=n;i>=1;--i){ add(Tool[i],1); ans+=ask(Tool[i]-1); } cout<<ans; return 0; }
12小时前 来自 浙江
0
有帮助,赞一个