分块

平方分割和分桶法

平方分割就是在维护一个数列上的某些信息时,通常将 O ( n ) O(\sqrt{n}) O(n )的元素分在一个桶内,分别维护每个桶内的信息。

这样当我们查询某些信息时就可以分为桶内查询和逐个查询,由于桶的数目为 O ( n ) O(\sqrt{n}) O(n )级别的,逐个查询的复杂度也是 O ( n ) O(\sqrt{n}) O(n )级别的,于是就将 O ( n 2 ) O(n^2) O(n2)降为了 O ( n n ) O(n\sqrt{n}) O(nn )

const int B = 1000;

int n, m, a[N], num[N];
vector<int> bucket[N / B];

void solve()
{
	rep(i, n) num[i] = a[i], bucket[i / B].push_back(a[i]);   // 一些预处理
    sort(num, num + n);
    rep(i, n / B) sort(bucket[i].begin(), bucket[i].end());

    while (m --){
        int l, r, k; scanf("%d%d%d", &l, &r, &k), l --;   // 左闭右开 [l, r) !!!

        int lb = 0, rb = n;
        while (rb - lb > 1){                     // do something
            int mid = (lb + rb) >> 1;
            int x = num[mid], c = 0;

            int tl = l, tr = r;
            for (; tl < min(tr, (tl + B - 1) / B * B); tl ++) if (a[tl] < x) c ++;
            for (; tr > max(tl, tr / B * B); tr --) if (a[tr - 1] < x) c ++;  // 逐个查询
            for (; tl < tr; tl += B){                    // 桶内查询 
                c += lower_bound(bucket[tl / B].begin(), bucket[tl / B].end(), x) - bucket[tl / B].begin();
            }
            
            if (c < k) lb = mid;
            else rb = mid;
        }

        printf("%d\n", num[lb]);
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值