在写题的时候偶然发现的 都是大佬
大概就是 将线段树接下来的 i<<1 和 i<<1|1改为了用一个数组l[i] 和r[i]来存储感觉很有意思 有一点点像链式前向星
#include <bits/stdc++.h>
#define mod 998244353
using namespace std;
typedef long long LL;
int c, d, X, ok, root[55];
int cnt, L[550005], R[550005], v[550005];
void update(int &k, int l, int r, int a, int b)
{
int m;
if (k == 0)
{
k = ++cnt;
v[k] = b;
}
if (v[k] > b)
v[k] = b;
if (l == r)
return;
m = (l + r) / 2;
if (a <= m)
update(L[k], l, m, a, b);
else
update(R[k], m + 1, r, a, b);
}
void query(int x, int l, int r)
{
int m;
if (ok || x == 0)
return;
if (l >= c && r <= d)
{
if (v[x] <= X)
ok = 1;
return;
}
m = (l + r) / 2;
if (c <= m)
query(L[x], l, m);
if (d >= m + 1)
query(R[x], m + 1, r);
}
int main()
{
int i, ans, opt, x, y;
while (1)
{
scanf("%d", &opt);
if (opt == 3)
break;
else if (opt == 0)
{
for (i = 1; i <= cnt; i++)
L[i] = R[i] = 0;
memset(root, 0, sizeof(root));
cnt = 0;
}
else if (opt == 1)
{
scanf("%d%d%d", &x, &y, &c);
update(root[c], 1, 1000000, y, x);
}
else if (opt == 2)
{
scanf("%d%d%d", &X, &c, &d);
ans = 0;
for (i = 0; i <= 50; i++)
{
ok = 0;
query(root[i], 1, 1000000);
ans += ok;
}
printf("%d\n", ans);
}
}
}