传送门biu~
对于某一区间[L,R]来说,所有线段中左端点小于R的线段数的是[1,R]的答案,在这部分答案中,右端点在L左侧的应该舍去,所以我们可以维护两个树状数组,一个存左端点出现次数,一个存右端点出现次数。
#include<cstdio>
using namespace std;
int n,m,a[50001],b[50001],k,l,r;
inline int ask1(int x){
int re=0;
for(;x;x-=x&-x)re+=a[x];
return re;
}
inline int ask2(int x){
int re=0;
for(;x;x-=x&-x)re+=b[x];
return re;
}
inline void add1(int x,int y){
for(;x<=n;x+=x&-x)a[x]+=y;
}
inline void add2(int x,int y){
for(;x<=n;x+=x&-x)b[x]+=y;
}
int main(){
scanf("%d%d",&n,&m);
while(m--){
scanf("%d%d%d",&k,&l,&r);
if(k==1){
add1(l,1);
add2(r,1);
}
else printf("%d\n",ask1(r)-ask2(l-1));
}
}
博客介绍了如何使用树状数组解决区间查询问题,特别是针对线段左端点和右端点的统计。通过维护两个树状数组,分别存储线段的左端点和右端点出现的次数,从而高效地排除不符合条件的线段。
2573

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



