zcmu1607: 大二下之悬梁刺股(树状数组)

链接:https://acm.zcmu.edu.cn/JudgeOnline/problem.php?id=1607

题目大意

n个数ai,q次询问,问1到x之间有几个数比a[x]大

思路

离散化+树状数组 离线处理

用unique离散化就知道了相对大小,然后可以用树状数组记录第i位之前有几位比他大了,记录ans数组,然后询问的时候直接访问ans数组

ac代码

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define lowbit(x) x&(-x)
const int maxn = 1e5 + 500;
int a[maxn], b[maxn], ans[maxn], c[maxn];
void add(int x, int k){
    for(int i = x; i < maxn; i += lowbit(i))
        c[i] += k;
}
int get(int x){
    int ans = 0;
    for(int i = x; i > 0; i -= lowbit(i))
        ans += c[i];
    return ans;
}
int main(){
    int n, q;
    while(~scanf("%d",&n)){
        if(n == -1) break;
        memset(c, 0, sizeof(c));
        for(int i = 1; i <= n; i ++){
            scanf("%d",&a[i]);
            b[i] = a[i];
        }
        sort(b + 1, b + n + 1);
        int m = unique(b + 1, b + n + 1) - b;
        for(int i = 1; i <= n; i ++){
            int x = (n + 5) - (lower_bound(b + 1, b + m + 1, a[i]) - b); //保证所有数都大于0就成
            ans[i] = get(x);
            add(x, 1);
        }
        scanf("%d",&q);
        while(q --){
            int x; scanf("%d",&x);
            printf("%d\n",ans[x]);
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_43911947/article/details/112353375