换个角度思考

换个角度思考

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;
}
全部评论

相关推荐

尊尼获获:闺蜜在哪?
点赞 评论 收藏
分享
11-01 20:03
已编辑
门头沟学院 算法工程师
Amazarashi66:这种也是幸存者偏差了,拿不到这个价的才是大多数
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务