大家都很强,可与之共勉。
我不会告诉你们我的输出优化错了,然后调了半天,Woc!
网上几乎都是数组实现的线段树与主席树,我就做一股清(zhuo)流好了。
题目是不带修改的查询区间第k大,注意主席树维护的性质为前缀和,所以是查询[l-1, r]。
然后query( )函数是用非递归形式写的二分查找,免得开栈占空间。其中各种强制&,因为YYF告诉我传参很慢。
代码如下
#include "cctype"
#include "cstdio"
#include "algorithm"
#define atoi(ch) (ch - 48)
template<typename T>
inline bool readIn(T &x) {
x = 0;
T flag = 1;
char ch;
while( !isdigit(ch = (char) getchar()) ) if(ch == '-') flag = -1;
x = atoi(ch);
while( isdigit(ch = (char) getchar()) )
x = (x << 1) + (x << 3) + atoi(ch);
x *= flag;
}
template<typename T>
inline void write( T x ) {
if(x > 9)
write(x / 10);
putchar(x % 10 + 48);
}
template<typename T>
inline bool writeIn(T x) {
if(x < 0) {
x = -x;
putchar('-');
}
write(x);
}
const int MAXN = (int) 1e5 + 5;
struct node {
int siz;
node *ls, *rs;
node() : siz(0), ls(NULL), rs(NULL) { }
inline bool update() {
siz = ls -> siz + rs -> siz;
}
} pool[MAXN * 20], *root[MAXN], *tail = pool, *null;
int n, m, l, r, k, rank[MAXN];
struct id {
int idx, x;
inline bool operator < (const id &rhs) const {
return x < rhs.x;
}
} a[MAXN];
void init() {
null = ++tail;
null -> siz = 0;
null -> ls = null -> rs = null;
readIn(n);readIn(m);root[0] = null;
for(register int i = 1; i <= n; root[i] = null, readIn(a[i].x), a[i].idx = i, ++i);
std::sort(a + 1, a + 1 + n);
for(register int i = 1; i <= n; rank[a[i].idx] = i, ++i);
}
node *insert(node *&pre, int lf, int rg, int &pos) {
if(pos < lf || pos > rg) return pre;
node *nd = ++tail;
if(lf == rg) {
nd -> siz = pre -> siz + 1;
return nd;
}
int mid = (lf + rg) >> 1;
nd -> ls = insert(pre -> ls, lf, mid, pos);
nd -> rs = insert(pre -> rs, mid + 1, rg, pos);
nd -> update();
return nd;
}
int query(int lf, int rg, int k) {
node *x = root[lf], *y = root[rg];
int l = 1, r = n;
while(l != r) {
int mid = (l + r) >> 1;
if( k <= x->ls->siz - y->ls->siz )
r = mid, x = x -> ls, y = y -> ls;
else
k -= (x->ls->siz - y->ls->siz),
l = mid + 1, x = x -> rs, y = y -> rs;
}
return l;
}
int main() {
init();
for(register int i = 1; i <= n; ++i)
root[i] = insert(root[i-1], 1, n, rank[i]);
while( m-- ) {
readIn(l), readIn(r), readIn(k);
writeIn(a[query(r, l - 1, k)].x);
putchar('\n');
}
return 0;
}