http://poj.org/problem?id=2104
http://poj.org/problem?id=2761
这两道题。。似乎是一样的。。。 = =
(我才不会说其实最开始是想交2104结果交城2761结果还Accept了。。。)
就是个主席树模板题。。静态区间第k大。。
其实用整体二分写的话更方便的。。不过无所谓了。。。反正学学高端的CMT嘛……
其实思路和整体二分也差不多的啊QAQ
离散化一下然后用权值建线段树。。
就是从前往后依次把树加入线段树 每次加入的时候新建这条链上的节点。。
然后查询的时候相减一下再二分就好了。。
我觉得我写的蛮简洁的 不服来辩2333
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int Nmax = 100005;
int N, Q, M;
int bfr[Nmax], aft[Nmax];
namespace CMT {
struct node {
node *lc, *rc;
int w, sum;
void clear() { lc = rc = NULL; w = sum = 0; }
void maintain()
{
sum = w;
if (lc) sum += lc -> sum;
if (rc) sum += rc -> sum;
}
}t[30 * Nmax], *root[4 * Nmax], *null = new node();
int tot;
inline void init() { tot = -1; for(int i = 0; i <= N; ++i) root[i] = NULL; }
inline node *NewNode() { t[++ tot].clear(); return &t[tot]; }
void update(node *an, node *&nw, int l, int r, int x)
{
nw = NewNode();
if (l == r) {
*nw = an ? *an : *null;
++ nw -> w; ++ nw -> sum;
return;
}
int mid = (l + r) >> 1;
if (x <= aft[mid]) {
update(an ? an -> lc : null, nw -> lc, l, mid, x);
nw -> rc = an ? an -> rc : NULL; nw -> maintain();
} else {
update(an ? an -> rc : null, nw -> rc, mid + 1, r, x);
nw -> lc = an ? an -> lc : NULL; nw -> maintain();
}
}
int query(node *L, node *R, int l, int r, int k)
{
if (l == r) return aft[l];
int mid = (l + r) >> 1, lsize = 0;
if (R && R -> lc) lsize += R -> lc -> sum;
if (L && L -> lc) lsize -= L -> lc -> sum;
if (lsize >= k) return query(L ? L -> lc : null, R ? R -> lc : null, l, mid, k);
return query(L ? L -> rc : null, R ? R -> rc : null, mid + 1, r, k - lsize);
}
}
int main()
{
while (~scanf("%d%d", &N, &Q)) {
for (int i = 1; i <= N; ++i) scanf("%d", &bfr[i]);
memcpy(aft + 1, bfr + 1, sizeof(aft[0]) * N);
sort(aft + 1, aft + N + 1);
M = unique(aft + 1, aft + N + 1) - aft - 1;
using namespace CMT; init();
for (int i = 1; i <= N; ++i) update(root[i - 1], root[i], 1, M, bfr[i]);
int L, R, rank;
for (int i = 1; i <= Q; ++i) {
scanf("%d%d%d", &L, &R, &rank);
printf("%d\n", query(root[L - 1], root[R], 1, M, rank));
}
}
return 0;
}