题解:P12359 [eJOI 2024] 古迹漫步 / Old Orhei
BlackPanda · · 题解
直接暴力查询复杂度是
发现点的数量很少,并且序列
struct Road {
int u, v; // A_u \sim A_v
} rd[N];
struct Tree {
int l, r;
int to[105];
} tree[N << 2];
int ls(int p) { return p << 1; }
int rs(int p) { return p << 1 | 1; }
void PushUp(int p) {
for (int i = 1; i <= n; i++) {
tree[p].to[i] = tree[rs(p)].to[tree[ls(p)].to[i]];
}
}
void Build(int p, int l, int r) {
tree[p].l = l;
tree[p].r = r;
if (tree[p].l == tree[p].r) {
for (int i = 1; i <= n; i++) tree[p].to[i] = i;
tree[p].to[rd[a[l]].u] = rd[a[l]].v;
} else {
int mid = (tree[p].l + tree[p].r) >> 1;
Build(ls(p), l + 0, mid);
Build(rs(p), mid + 1, r);
PushUp(p);
}
}
void Change(int p, int x, int d) {
if (tree[p].l == tree[p].r) {
for (int i = 1; i <= n; i++) tree[p].to[i] = i;
tree[p].to[rd[d].u] = rd[d].v;
} else {
int mid = (tree[p].l + tree[p].r) >> 1;
if (x <= mid)Change(ls(p), x, d);
if (mid < x) Change(rs(p), x, d);
PushUp(p);
}
}
int Ask(int p, int l, int r, int s) {
if (l <= tree[p].l && tree[p].r <= r) {
return tree[p].to[s];
} else {
int res = s;
int mid = (tree[p].l + tree[p].r) >> 1;
if (l <= mid) res = Ask(ls(p), l, r, res);
if (mid < r) res = Ask(rs(p), l, r, res);
return res;
}
}
/*====================*/
void Solve() {
cin >> n >> m;
for (int i = 1; i <= m; i++) {
int u, v; cin >> u >> v;
rd[i].u = u;
rd[i].v = v;
}
cin >> t;
for (int i = 1; i <= t; i++) {
cin >> a[i];
}
Build(1, 1, t);
cin >> q;
while (q--) {
int op, l, r;
cin >> op >> l >> r;
if (op == 1) {
int s; cin >> s;
cout << Ask(1, l, r, s) << endl;
} else {
Change(1, l, r);
}
}
return;
}