分块WA19个点求调
查看原帖
分块WA19个点求调
477443
vegetable_kingGallium楼主2021/12/5 12:11
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>

using namespace std;

int k, len, st[401], ed[401], a[100001], b[100001], bel[100001];
void init(int n){
	k = len = sqrt(n);
	for (int i = 1;i <= k;i ++){
		st[i] = len * (i - 1) + 1;
		ed[i] = len * i;
	}
	if (len * k < n) st[++ k] = ed[len] + 1, ed[k] = n;
	memcpy(b, a, sizeof(a));
	for (int i = 1;i <= k;i ++){
		sort(b + st[i], b + ed[i] + 1);
		for (int j = st[i];j <= ed[i];j ++) bel[j] = i;
	}
}
void update(int p, int x){
	int bp = bel[p];
	a[p] = x;
	for (int i = st[bp];i <= ed[bp];i ++) b[i] = a[i];
	sort(b + st[bp], b + ed[bp] + 1);
}
int query(int l, int r, int x){
	int bl = bel[l], br = bel[r], ans = 0;
	if (l != st[bl]){
		for (int i = l;i <= ed[bl];i ++){
			if (a[i] < x) ans ++;
		}
		bl ++;
	}
	if (r != ed[br]){
		for (int i = st[br];i <= r;i ++){
			if (a[i] < x) ans ++;
		}
		br --;
	}
	for (int i = bl;i <= br;i ++){
		int add = lower_bound(b + st[i], b + ed[i] + 1, x) - b - st[i];
		//printf("%d\n", add);
		ans += add;
	}
	return ans;
}
int kth(int l, int r, int k){
	int L = -1e9, R = 1e9 + 1, mid;
	while (R - L > 1){
		mid = (L + R) / 2;
		if (query(l, r, mid) >= k) R = mid;
		else L = mid;
	}
	return L;
}
int n, m, l, r, x;
char op;
int main(){
	scanf("%d%d", &n, &m);
	for (int i = 1;i <= n;i ++) scanf("%d", &a[i]);
	init(n);
	while (m --){
		scanf(" %c%d%d", &op, &l, &r);
		if (op == 'Q') scanf("%d", &x), printf("%d\n", kth(l, r, x));
		else update(l, r);
	}
}
2021/12/5 12:11
加载中...