没有困难的树状数组,只有勇敢的作者。(雾
还没有树状数组的题解,赶紧来一发。
题目大意
给定你 nnn 个地址,在第 aia_iai 位置有 pip_ipi 个人。给定 qqq 个询问,每次查询 lil_ili 到 rir_iri 中有多少个人。
思路
显然,区间问题选择树状数组。
但是太大了,怎么处理?显然,最多不重复坐标为 n+2×qn+2\times qn+2×q。所以直接把所有出现过的坐标离散化即可。
代码(见其他题解的二分,这里不多说)
#include<bits/stdc++.h>
using namespace std;
const long long MAXN=2e5;
long long n,q;
long long a[MAXN+1],b[MAXN+1];
int main(){
cin>>n;
for(long long i=1;i<=n;i++)cin>>a[i];
for(long long i=1;i<=n;i++){
cin>>b[i];b[i]=b[i-1]+b[i];
}
cin>>q;
while(q--){
long long x,y;cin>>x>>y;
long long r=upper_bound(a+1,a+1+n,y)-a-1;
long long l=lower_bound(a+1,a+1+n,x)-a;
if(r<l)cout<<0<<'\n';
else{
cout<<b[r]-b[l-1]<<'\n';
}
}
return 0;
}
代码(树状数组)
#include<bits/stdc++.h>
using namespace std;
long long tree[600010],N,Q;
long long lowbit(long long x){
return x&-x;
}
void update(long long x,long long d){
while(x<=N+2*Q){
tree[x]+=d;
x+=lowbit(x);
}
}
long long sum(long long x){
long long ans=0;
while(x>=1){
ans+=tree[x];
x-=lowbit(x);
}
return ans;
}
pair<long long,pair<long long,bool> >G[600010];
long long x[200001],y[200001];
unordered_map<long long,long long>up;
int main(){
cin>>N;
for(long long i=1;i<=N;i++){
cin>>G[i].first;
}
for(long long i=1;i<=N;i++){
cin>>G[i].second.first;
}cin>>Q;
for(long long i=1;i<=Q;i++){
cin>>G[2*i-1+N].first>>G[2*i+N].first;
G[2*i-1+N].second.second=true;
G[2*i+N].second.second=true;
x[i]=G[2*i-1+N].first,y[i]=G[2*i+N].first;
}
sort(G+1,G+1+N+2*Q);
long long maxp=-LLONG_MAX,X=0;
for(long long i=1;i<=N+2*Q;i++){
if(G[i].first==maxp){
if(!G[i].second.second){
update(up[G[i].first],G[i].second.first);
}
}
else{
maxp=G[i].first;X++;
up[maxp]=X;
if(!G[i].second.second){
update(up[G[i].first],G[i].second.first);
}
}
}
for(long long i=1;i<=Q;i++){
cout<<sum(up[y[i]])-sum(up[x[i]]-1)<<'\n';
}
return 0;
}
1D Country 树状数组题解
2132

被折叠的 条评论
为什么被折叠?



