poj 2104 K-th Number 区间第K大 二分 离散化 + (莫队 树状数组/平方分解/线段树)

博客详细介绍了POJ 2104题目的解决方案,包括使用莫队算法配合树状数组、平方分解以及线段树的解法。离散化数据后,通过莫队算法可以在较短时间内找到答案,而平方分解方法适合处理部分数据,线段树则提供了一种在树结构上进行区间查询的手段。三种方法各有优缺点,如莫队算法快速但代码较长,线段树代码简洁但效率稍低。
摘要由CSDN通过智能技术生成

题目

题目链接:http://poj.org/problem?id=2104

题目来源:《挑战》例题。

简要题意:求区间第 k 大。

题解

比较经典的题目,我用了三个方法来写。

其中第一种第三种我觉得比较好写,第二种出现了各种问题。

总的来说第一种速度快,但是代码长,第三种速度慢一些,但是代码比较短,第二种代码和第三种差不多,但是慢了很多,写起来很蛋疼。

第一种是我自己写的写法,后两种是书上的写法。好像还可以用其他乱七八糟树来弄。

题解1

首先可以离散化一下数据。

然后莫队去搞,然后用树状数组来维护整个个数,再去二分答案。

整个代码比较长,不过写起来还是比较方便的。

莫队+树状数组代码

#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <stack>
#include <queue>
#include <string>
#include <vector>
#include <set>
#include <map>
#define fi first
#define se second
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;
// head
const int N = 1e5+5;
const int M = 5e3+5;
const int B = 1000;

struct BIT {
#define T int
    T tree[N] ;
    inline int lowbit(int x) {
        return x&(-x);
    }
    void add(int x, T add, int n) {
        for (int i = x; i <= n; i += lowbit(i)) {
            tree[i] += add;
        }
    }
    T sum(int x) {
        T ans = 0;
        for (int i = x; i > 0; i -= lowbit(i)) {
            ans += tree[i];
        }
        return ans;
    }
    T query(int k, int n) {
        int l = 1, r = n, ans = n;
        while (l <= r) {
            int mid = (l + r) / 2;
            if (sum(mid) >= k) {
                ans = mid;
                r = mid-1;
            } else {
                l = mid+
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值