#include <bits/stdc++.h>
using namespace std;
const int N=3e5+10;
const int mod = 998244353;
typedef long long ll;
typedef unsigned long long ull;
const ll INF = 2e9;
ll n,m;
ll ans[N];
struct Query
{
ll l,r,x;
int id;
}q[N];
struct Node
{
ll v,idx;
}a[N];
bool cmp(Query a,Query b)
{
return a.x<b.x;
}
bool cmp2(Node a,Node b)
{
return a.v<b.v;
}
struct BIT {
int n;
vector<int> tr;
BIT() {}
BIT(int n) { init(n); }
void init(int _n) {
n = _n;
tr.assign(n + 1, 0);
}
void add(int x, int v) {
for (; x <= n; x += x & -x) tr[x] += v;
}
int sum(int x) {
int res = 0;
for (; x > 0; x -= x & -x) res += tr[x];
return res;
}
int query(int l, int r) {
if (l > r) return 0;
return sum(r) - sum(l - 1);
}
};
void solve()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
{
cin>>a[i].v;
a[i].idx = i;
}
sort(a+1,a+1+n,cmp2);
BIT b1(N);
for(int i=1;i<=m;i++)
{
cin>>q[i].l>>q[i].r>>q[i].x;
q[i].id = i;
}
sort(q+1,q+1+m,cmp);
int idx = 1;
for(int i=1;i<=m;i++)
{
while(idx<=n&&a[idx].v<=q[i].x)
{
b1.add(a[idx].idx,1);
idx++;
}
ans[q[i].id] = b1.query(q[i].l, q[i].r);
}
for(int i=1;i<=m;i++)
{
cout<<ans[i]<<'\n';
}
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int t=1;
// cin>>t;
while(t--)
{
solve();
}
return 0;
}
用的树状数组,加二次排序做的,由于求的值域是从1到x所以我们可以先讲a数组按照v大小排序,然后讲q也按照x的大小排序
,然后每次查询,讲小于等于x的所有a添加进树状数组中,然后求区间之和即可

京公网安备 11010502036488号