結果
| 問題 |
No.2809 Sort Query
|
| コンテスト | |
| ユーザー |
chro_96
|
| 提出日時 | 2024-07-12 23:25:27 |
| 言語 | C (gcc 13.3.0) |
| 結果 |
AC
|
| 実行時間 | 1,227 ms / 2,000 ms |
| コード長 | 3,656 bytes |
| コンパイル時間 | 1,498 ms |
| コンパイル使用メモリ | 32,436 KB |
| 実行使用メモリ | 28,800 KB |
| 最終ジャッジ日時 | 2024-07-12 23:26:26 |
| 合計ジャッジ時間 | 57,430 ms |
|
ジャッジサーバーID (参考情報) |
judge6 / judge4 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 71 |
ソースコード
#include <stdio.h>
#include <stdlib.h>
int cmp_ll (const void *ap, const void *bp) {
long long a = *(long long *)ap;
long long b = *(long long *)bp;
if (a < b) {
return -1;
}
if (a > b) {
return 1;
}
return 0;
}
void add_segt (int *t, int idx, int val, int size) {
idx = idx+size-1;
t[idx] += val;
while (idx > 0) {
idx = (idx-1)/2;
t[idx] += val;
}
return;
}
int sum_segt_rec (int *t, int a, int b, int k, int l, int r) {
if (r <= a || b <= l) {
return 0;
}
if (a <= l && r <= b) {
return t[k];
}
return sum_segt_rec(t, a, b, 2*k+1, l, (l+r)/2)+sum_segt_rec(t, a, b, 2*k+2, (l+r)/2, r);
}
int sum_segt (int *t, int a, int b, int size) {
return sum_segt_rec(t, a, b, 0, 0, size);
}
int main () {
int n = 0;
int q = 0;
long long a[300000] = {};
int t[300000] = {};
int k[300000] = {};
long long x[300000] = {};
int res = 0;
long long val[600000] = {};
int val_cnt = 1;
int w[300000] = {};
int prev = 0;
int segt[2097151] = {};
int size = 1;
int tmp[300000] = {};
res = scanf("%d", &n);
res = scanf("%d", &q);
for (int i = 0; i < n; i++) {
res = scanf("%lld", a+i);
val[i] = a[i];
}
for (int i = 0; i < q; i++) {
res = scanf("%d", t+i);
if (t[i] != 2) {
res = scanf("%d", k+i);
if (t[i] == 1) {
res = scanf("%lld", x+i);
val[i+n] = x[i];
}
}
}
qsort(val, n+q, sizeof(long long), cmp_ll);
for (int i = 1; i < n+q; i++) {
if (val[i-1] != val[i]) {
val[val_cnt] = val[i];
val_cnt++;
}
}
for (int i = 0; i < n; i++) {
int idx[2] = { 0, val_cnt };
while (idx[1]-idx[0] > 1) {
int nxt = (idx[0]+idx[1])/2;
if (val[nxt] > a[i]) {
idx[1] = nxt;
} else {
idx[0] = nxt;
}
}
a[i] = (long long)idx[0];
}
for (int i = 0; i < q; i++) {
int idx[2] = { 0, val_cnt };
while (idx[1]-idx[0] > 1) {
int nxt = (idx[0]+idx[1])/2;
if (val[nxt] > x[i]) {
idx[1] = nxt;
} else {
idx[0] = nxt;
}
}
x[i] = (long long)idx[0];
}
while (size <= val_cnt) {
size <<= 1;
}
for (int i = 0; i < n; i++) {
add_segt(segt, (int)a[i], 1, size);
}
for (int i = 0; i < q; i++) {
if (t[i] == 1 && prev > 0) {
a[k[i]-1] = x[i];
w[k[i]-1] = i;
} else if (t[i] == 1) {
add_segt(segt, (int)a[k[i]-1], -1, size);
add_segt(segt, (int)x[i], 1, size);
a[k[i]-1] = x[i];
w[k[i]-1] = i;
} else if (t[i] == 2 && prev > 0) {
for (int j = prev; j < i; j++) {
if (t[j] == 1 && w[k[j]-1] == j) {
int idx[2] = { -1, val_cnt-1 };
while (idx[1]-idx[0] > 1) {
int nxt = (idx[0]+idx[1])/2;
if (sum_segt(segt, 0, nxt+1, size) < k[j]) {
idx[0] = nxt;
} else {
idx[1] = nxt;
}
}
tmp[j] = idx[1];
}
}
for (int j = prev; j < i; j++) {
if (t[j] == 1 && w[k[j]-1] == j) {
add_segt(segt, tmp[j], -1, size);
add_segt(segt, (int)x[j], 1, size);
}
}
prev = i+1;
} else if (t[i] == 2) {
prev = i+1;
} else if (w[k[i]-1] >= prev) {
printf("%lld\n", val[a[k[i]-1]]);
} else {
int idx[2] = { -1, val_cnt-1 };
while (idx[1]-idx[0] > 1) {
int nxt = (idx[0]+idx[1])/2;
if (sum_segt(segt, 0, nxt+1, size) < k[i]) {
idx[0] = nxt;
} else {
idx[1] = nxt;
}
}
printf("%lld\n", val[idx[1]]);
}
}
return 0;
}
chro_96