换个角度思考
换个角度思考
https://ac.nowcoder.com/acm/problem/19427
题意
给定序列,多次查询,每次查询一个区间内小于某个数的个数。
思路
题目疯狂暗示换个角度思考🤔,我就先姑且试试。开始先想到的是用一堆桶存对应数的下标,这样对于一次查询 我们只需要在那些<=k的桶里找下标处于
的个数,考虑到有多个查询,我们可以利用单调性先将查询排个序,离线处理。接下来就是数数的问题了,开始想的是用差分和前缀和,后来想想好像不太行(每得出一次查询都是
),由于点进题目之前瞄到了一眼数状数组,遂尝试了一波,可(大雾)。
复杂度
代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define pb push_back
#define db double
#define mp make_pair
#define fi first
#define se second
#define de(a) cout << #a << " = " << a << endl
const int maxn = 1e5 + 10;
int ans[maxn], c[maxn];
struct Query{
int l, r, val, id;
bool friend operator < (Query a, Query b){
return a.val < b.val;
}
};
int n, m;
Query q[maxn];
vector<int> num[maxn];
void add(int x, int val){
for(; x <= n; x += x & (-x)){
c[x] += val;
}
}
int f(int x){
int res = 0;
for(; x > 0; x -= x & (-x)){
res += c[x];
}
return res;
}
int main()
{
cin >> n >> m;
for(int i = 1; i <= n; i++){
int t;
cin >> t;
num[t].pb(i);
}
for(int i = 0; i < m; i++){
cin >> q[i].l >> q[i].r >> q[i].val;
q[i].id = i;
}
sort(q, q + m);
for(int i = 1, idx = 0; i < maxn; i++){
while(idx < m && q[idx].val < i){ //这里是while, 不是if QAQ
//de(q[idx].val);
ans[q[idx].id] = f(q[idx].r) - f(q[idx].l - 1);
idx++;
}
for(int v : num[i]){
add(v, 1);
}
}
for(int i = 0; i < m; i++){
cout << ans[i] << endl;
}
return 0;
} 