整体二分求助
查看原帖
整体二分求助
148851
StevenLu1103楼主2020/7/22 09:30

样例都没过。

采用了和整体二分题解不一样的写法,感觉是对的,但是过不了样例。

#include <stdio.h>
#include <ctype.h>
#include <algorithm>
#define R register
#define N 200005
char Buf[1 << 24], *S(Buf), *T(Buf);
#define getchar() (S == T && (T = (S = Buf) + fread(Buf, 1, 1 << 24, stdin), S == T) ? EOF : *S++)
inline int input() {
    R int x(0), f(0);
    R char c(getchar());
    while (!isdigit(c)) f |= (c == '-'), c = getchar();
    while (isdigit(c)) x = (x << 1) + (x << 3) + (c ^ 48), c = getchar();
    return f ? -x : x;
}
struct Data {
	int pos, x;
	inline Data(int POS = 0, int X = 0) : pos(POS), x(X) {}
	inline bool operator < (const Data &b) { return x < b.x; }
};
Data a[N], b[N], Al[N], Ar[N];
struct Query {
	int l, r, k, pos;
	inline Query() {}
	inline Query(int X, int Y, int K, int POS) : l(X), r(Y), k(K), pos(POS) {}
};
Query q[N], Ql[N], Qr[N];
int n, m, tot, val[N], c[N], ans[N];
inline void Add(R int x) {
	for (; x <= n; x += x & -x) ++c[x];
}
inline void Minus(R int x) {
	for (; x <= n; x += x & -x) --c[x];
}
inline int Sum(R int x) {
	R int ret(0);
	for (; x; x -= x & -x) ret += c[x];
	return ret;
}
void solve(int x, int y, int QL, int QR, int l, int r) {//QL,QR 是询问边界,l,r是对应原数列边界,x,y是对应的值域范围
	if (x == y) {
		for (int i(QL); i <= QR; ++i) ans[q[i].pos] = x;
		return;
	}
	int mid(x + y >> 1), A(0), B(0), C(0), D(0);
	for (R int i(l); i <= r; ++i)
		if (a[i].x <= mid)
			Add(a[i].pos), Al[++A] = a[i];
		else
			Ar[++B] = a[i];
	for (R int i(QL); i <= QR; ++i) {
		int cnt = Sum(q[i].r) - Sum(q[i].l - 1);
		if (q[i].k <= cnt)
			Ql[++C] = q[i];
		else
			q[i].k -= cnt, Qr[++D] = q[i];
	}
	for (R int i(l); i <= r; ++i) Minus(a[i].pos);
	for (R int i(1); i <= A; ++i) a[l + i - 1] = Al[i];
	for (R int i(1); i <= B; ++i) a[l + i + A - 1] = Ar[i];
	for (R int i(1); i <= C; ++i) q[QL + i - 1] = Ql[i];
	for (R int i(1); i <= D; ++i) q[QL + i + C - 1] = Qr[i];
	solve(x, mid, QL, QL + C - 1, l, l + A - 1);
	solve(mid + 1, y, QL + C, QR, l + A, r);
}
int main() {
	n = input(), m = input();
	for (int i(1); i <= n; ++i) b[i] = Data(i, input());
	std :: sort(b + 1, b + n + 1);
	for (int i(1); i <= n; ++i) {
		if (i == 1 || b[i].x != b[i - 1].x)
			a[b[i].pos].x = ++tot;
		else
			a[b[i].pos].x = tot;	
		a[i].pos = i, val[tot] = b[i].x;	
	}
	for (int i(1); i <= m; ++i) {
		int l(input()), r(input());
		q[i] = Query(l, r, input(), i);
	}
	//for (int i = 1; i <= n; ++i) printf("a[%d] -> pos = <%d>, a[%d] -> x = <%d>\n", i, a[i].pos, i, a[i].x);
	solve(1, tot, 1, m, 1, n);
	for (int i = 1; i <= m; ++i) printf("%d\n", val[ans[i]]);
    return 0;
}
2020/7/22 09:30
加载中...