题解:P10814 【模板】离线二维数点
jiayixuan1205 · · 题解
题意
在一段区间内查询小于等于
分析
可以将每个点看作平面直角坐标系上以横坐标为下标,纵坐标为该点值的一个点,那么该问题就可以转化为一个在矩形中扫描寻找值小于等于
代码展示
#include<bits/stdc++.h>
using namespace std;
const int N = 2e6+10;
int l,r,x,n,m;
int a[N],ans[N],tree[N];//ans用来存储每次询问的答案,a存储序列,tree用于树状数组的操作
struct node{
int id,x,v;
};
vector<node> c[N];//相当于差分处理的一个数组
inline int lowbit(int x)
{
return x&(-x);
}
inline void add(int x)
{
for(int i=x;i<N;i+=lowbit(i))
{
tree[i]++;
}
}
inline int ask(int x)
{
int ans=0;
for(int i=x;i>=1;i-=lowbit(i)) ans+=tree[i];//记录区间内的答案
return ans;
}
int main()
{
std::ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>n>>m;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=m;i++)
{
cin>>l>>r>>x;
c[l-1].push_back({i,x,-1});
c[r].push_back({i,x,1});//记录每个询问的左右端点差分
}
for(int i=1;i<=n;i++)
{
add(a[i]);//计入树状数组
for(int j=0;j<c[i].size();j++)
{
ans[c[i][j].id]+=c[i][j].v*(ask(c[i][j].x));//记录答案
}
}
for(int i=1;i<=m;i++) cout<<ans[i]<<endl;
return 0;
}