代码
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cstdlib>
#include <cctype>
#include <map>
#include <set>
#include <vector>
#include <iostream>
#include <cmath>
#define pk putchar(' ')
#define ph puts("")
typedef long long ll;
const int N = 1e5 + 5, INF = (1ll << 31) - 1;
using namespace std;
int n, m, a[N];
int rt[N], cnt, tmp[N], tot, t1[N], t2[N], tot1, tot2;
struct node
{
int ls, rs, sum;
} t[N << 7];
struct ques
{
int l, r, val, Or;
} as[N];
int lowbit(int x)
{
return x & -x;
}
void modify(int &now, int l, int r, int pos, int val)
{
if (!now)
now = ++cnt;
if (l == r) {
t[now].sum += val;
return;
}
int Mid = (l + r) >> 1;
if (pos <= Mid)
modify(t[now].ls, l, Mid, pos, val);
else
modify(t[now].rs, Mid + 1, r, pos, val);
t[now].sum = t[t[now].ls].sum + t[t[now].rs].sum;
}
void premodify(int pos, int val)
{
for (int i = pos; i <= n; i += lowbit(i)) modify(rt[i], 1, tot, a[pos], val);
}
int query(int x, int l, int r, int k)
{
if (l == r)
return t[x].sum;
int Mid = (l + r) >> 1;
if (k <= Mid)
return query(t[x].ls, l, Mid, k);
else
return t[t[x].ls].sum + query(t[x].rs, Mid + 1, r, k);
}
int get_rank(int l, int r, int k)
{
int res = 0;
l--;
for (int i = r; i > 0; i -= lowbit(i))
res += query(rt[i], 1, tot, k);
for (int i = l; i > 0; i -= lowbit(i))
res -= query(rt[i], 1, tot, k);
return res;
}
int xth(int l, int r, int k)
{
int Mid = (l + r) >> 1;
if (l == r)
return Mid;
int res = 0;
for (int i = 1; i <= tot1; i++) res += t[t[t1[i]].ls].sum;
for (int i = 1; i <= tot2; i++) res -= t[t[t2[i]].ls].sum;
if (res >= k)
{
for (int i = 1; i <= tot1; i++) t1[i] = t[t1[i]].ls;
for (int i = 1; i <= tot2; i++) t2[i] = t[t2[i]].ls;
return xth(l, Mid, k);
}
else
{
for (int i = 1; i <= tot1; i++) t1[i] = t[t1[i]].rs;
for (int i = 1; i <= tot2; i++) t2[i] = t[t2[i]].rs;
return xth(Mid + 1, r, k - res);
}
}
int get_xth(int l, int r, int k)
{
l--;
tot1 = 0, tot2 = 0;
for (int i = r; i > 0; i -= lowbit(i))
t1[++tot1] = rt[i];
for (int i = l; i > 0; i -= lowbit(i))
t2[++tot2] = rt[i];
return tmp[xth(1, tot, k)];
}
template <class T>
void rd(T &x)
{
x = 0;
int f = 1;
char c = getchar();
while (!isdigit(c)) {if (c == '-') f = -1; c = getchar();}
while (isdigit(c)) x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();
x *= f;
}
template <class T>
void pt(T x)
{
if (x < 0)
putchar('-'), x = (~x) + 1;
if (x > 9)
pt(x / 10);
putchar(x % 10 ^ 48);
}
int main()
{
rd(n), rd(m);
for (int i = 1; i <= n; i++)
rd(a[i]), tmp[i] = a[i];
tot = n;
for (int i = 1; i <= m; i++)
{
rd(as[i].Or);
switch (as[i].Or)
{
case 3:
{
rd(as[i].l);
rd(as[i].val);
tmp[++tot] = as[i].val;
break;
}
default:
{
rd(as[i].l);
rd(as[i].r);
rd(as[i].val);
if (as[i].Or != 2)
tmp[++tot] = as[i].val;
break;
}
}
}
sort(tmp + 1, tmp + 1 + tot);
tot = unique(tmp + 1, tmp + 1 + tot) - tmp - 1;
for (int i = 1; i <= n; i++)
a[i] = lower_bound(tmp + 1, tmp + 1 + tot, a[i]) - tmp, premodify(i, 1);
for (int i = 1; i <= m; i++)
switch (as[i].Or)
{
case 1:
{
as[i].val = lower_bound(tmp + 1, tmp + 1 + tot, as[i].val) - tmp;
pt(get_rank(as[i].l, as[i].r, as[i].val - 1) + 1), ph;
break;
}
case 2:
{
pt(get_xth(as[i].l, as[i].r, as[i].val)), ph;
break;
}
case 3:
{
premodify(as[i].l, -1);
a[as[i].l] = lower_bound(tmp + 1, tmp + 1 + tot, as[i].val) - tmp;
premodify(as[i].l, 1);
break;
}
case 4:
{
as[i].val = lower_bound(tmp + 1, tmp + 1 + tot, as[i].val) - tmp;
int pre = get_rank(as[i].l, as[i].r, as[i].val - 1);
int ans = get_xth(as[i].l, as[i].r, pre);
if (pre == 0)
pt(-INF), ph;
else
pt(ans), ph;
break;
}
default:
{
as[i].val = lower_bound(tmp + 1, tmp + 1 + tot, as[i].val) - tmp;
int bac = get_rank(as[i].l, as[i].r, as[i].val);
int ans = get_xth(as[i].l, as[i].r, bac + 1);
if (bac == as[i].r - as[i].l + 1)
pt(INF), ph;
else
pt(ans), ph;
break;
}
}
return 0;
}
Thanks!