是我写假了吗
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 5e4 + 5;
const int MAXM = 1e7 + 5;
const int INF = 2147483647;
int n, m, a[MAXN];
inline int read()
{
int s = 0, f = 1;
char ch = getchar();
while (ch < 48 || ch > 57)
{
if (ch == '-')
f = -1;
ch = getchar();
}
while (ch >= 48 && ch <= 57)
{
s = (s << 3) + (s << 1) + (ch ^ 48);
ch = getchar();
}
return s * f;
}
namespace FHQ
{
int ch[MAXM][2], pri[MAXM], sz[MAXM], val[MAXM], tot = 0;
// --- bottom ---
inline int Add(int x)
{
val[++tot] = x;
pri[tot] = rand();
sz[tot] = 1;
return tot;
}
inline void push_up(int x)
{
sz[x] = sz[ch[x][0]] + sz[ch[x][1]] + 1;
}
int Merge(int x, int y)
{
if (!x || !y)
return x + y;
if (pri[x] < pri[y])
{
ch[x][1] = Merge(ch[x][1], y);
push_up(x);
return x;
}
else
{
ch[y][0] = Merge(x, ch[y][0]);
push_up(y);
return y;
}
}
void Split(int cur, int k, int &x, int &y)
{
if (!cur)
{
x = y = 0;
return;
}
if (val[cur] <= k)
{
x = cur;
Split(ch[cur][1], k, ch[cur][1], y);
}
else
{
y = cur;
Split(ch[cur][0], k, x, ch[cur][0]);
}
push_up(cur);
}
int Find(int cur, int k)
{
while (true)
if (sz[ch[cur][0]] >= k)
cur = ch[cur][0];
else if (sz[ch[cur][0]] + 1 == k)
return cur;
else
{
k -= sz[ch[cur][0]] + 1;
cur = ch[cur][1];
}
}
// --- application ---
inline void Insert(int &root, int k)
{
int x, y;
Split(root, k, x, y);
root = Merge(x, Merge(Add(k), y));
}
inline void Delete(int &root, int k)
{
int x, y, z;
Split(root, k, x, z);
Split(x, k - 1, x, y);
y = Merge(ch[y][0], ch[y][1]);
root = Merge(x, Merge(y, z));
}
inline int Rank(int root, int k)
{
int x, y;
Split(root, k - 1, x, y);
int ans = sz[x] + 1;
root = Merge(x, y);
return ans;
}
inline int Last(int root, int k)
{
int x, y;
Split(root, k - 1, x, y);
int ans = sz[x] ? val[Find(x, sz[x])] : -INF;
root = Merge(x, y);
return ans;
}
inline int Next(int root, int k)
{
int x, y;
Split(root, k, x, y);
int ans = sz[y] ? val[Find(y, 1)] : INF;
root = Merge(x, y);
return ans;
}
// --- level 2 application ---
inline void build(int &root, int l, int r)
{
for (int i = l; i <= r; i++)
Insert(root, a[i]);
}
}
namespace SegTree
{
int t[MAXN << 2], root[MAXN << 2];
inline int ls(int p)
{
return p << 1;
}
inline int rs(int p)
{
return p << 1 | 1;
}
void build(int p, int l, int r)
{
FHQ::build(root[p], l, r);
if (l == r)
return;
int mid = l + r >> 1;
build(ls(p), l, mid);
build(rs(p), mid + 1, r);
}
void update(int p, int l, int r, int pre, int k)
{
FHQ::Delete(root[p], a[pre]);
FHQ::Insert(root[p], k);
if (l == r)
return;
int mid = l + r >> 1;
if (pre <= mid)
update(ls(p), l, mid, pre, k);
else
update(rs(p), mid + 1, r, pre, k);
}
int Rank(int p, int qx, int qy, int l, int r, int k)
{
if (qx > r || qy < l)
return 0;
if (qx <= l && r <= qy)
return FHQ::Rank(root[p], k) - 1;
int mid = l + r >> 1;
return Rank(ls(p), qx, qy, l, mid, k) + Rank(rs(p), qx, qy, mid + 1, r, k);
}
int Find(int l, int r, int k)
{
int x = 0, y = 1e8;
while (x <= y)
{
int mid = x + y >> 1;
if (Rank(1, l, r, 1, n, mid) + 1 <= k)
x = mid + 1;
else
y = mid - 1;
}
return x - 1;
}
int Last(int p, int qx, int qy, int l, int r, int k)
{
if (qx > r || qy < l)
return -INF;
if (qx <= l && r <= qy)
return FHQ::Last(root[p], k);
int mid = l + r >> 1;
return max(Last(ls(p), qx, qy, l, mid, k), Last(rs(p), qx, qy, mid + 1, r, k));
}
int Next(int p, int qx, int qy, int l, int r, int k)
{
if (qx > r || qy < l)
return INF;
if (qx <= l && r <= qy)
return FHQ::Next(root[p], k);
int mid = l + r >> 1;
return min(Next(ls(p), qx, qy, l, mid, k), Next(rs(p), qx, qy, mid + 1, r, k));
}
}
int main()
{
// ios::sync_with_stdio(false);
// cin.tie(nullptr);
// freopen("t.in", "r", stdin);
n = read();
m = read();
for (int i = 1; i <= n; i++)
a[i] = read();
SegTree::build(1, 1, n);
int op, x, y, z;
while (m--)
{
op = read();
x = read();
y = read();
if (op == 3)
{
SegTree::update(1, 1, n, x, y);
a[x] = y;
continue;
}
z = read();
switch (op)
{
case 1:
printf("%d\n", SegTree::Rank(1, x, y, 1, n, z) + 1);
break;
case 2:
printf("%d\n", SegTree::Find(x, y, z));
break;
case 4:
printf("%d\n", SegTree::Last(1, x, y, 1, n, z));
break;
default:
printf("%d\n", SegTree::Next(1, x, y, 1, n, z));
}
}
return 0;
}
我看题解区有人写FHQ的啊,,