poj 3264 Balanced Lineup

本文介绍了一种使用分桶法(块状数组)的数据结构优化方法,并提供了一个具体的C++实现案例。该方法通过对数据进行分块并分别排序来加速区间查询操作,适用于需要频繁进行区间最大值和最小值查询的应用场景。
/*
分桶法/块状数组
*/
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;

#define MAX_N 50000
#define B  250
#define INF  0x3f3f3f

typedef long long ll;
int N;
int Q,a,b;

void solve(int arr[]){
        vector <int> backet[MAX_N / B];
        for(int i = 0;i < N; i++){
                backet[i / B].push_back(arr[i]);
        }

        //对每个桶进行排序
        for(int i = 0;i <=N / B; i++)
                sort(backet[i].begin(), backet[i].end());
        /*for(int i = 1;i <= N; i++)
                printf("%d ", arr[i]);
        printf("\n");
        */
        for(int i = 0;i < Q; i++){
                scanf("%d%d", &a, &b);
                int l = a, r = b+1;

                int maxx = 0, minn = INF;
                if(l == r) {printf("0\n"); continue;}

                //对桶外元素进行查找
                while(l < r && l % B != 0) {
                        if(arr[l] > maxx)
                                maxx = arr[l];
                        if(arr[l] < minn) 
                                minn = arr[l];
                        l++;
                }
                while(l < r && r % B != 0){     
                        if(arr[r] < minn)
                                minn = arr[r];
                        if(arr[r] > maxx)
                                maxx = arr[r];
                        
                }
                //对桶内元素进行查找
                while(l < r){
                        vector <int>::iterator it;
                        it = backet[l/B].begin();
                        minn = min(*it, minn);
                        it = backet[l/B].end();
                        maxx = max(*it, maxx);
                        l += B;
                }
                int ans = maxx - minn;
                printf("%d\n", ans);

        }
}

int main(){
        scanf("%d%d", &N, &Q);
        int arr[MAX_N];
        memset(arr, 0, sizeof(arr));
        for(int i = 1;i <= N; i++){
                scanf("%d", &arr[i]);
        }

        solve(arr);

        return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值