【树链剖分】大冰隙2
题意
给出一个01序列,序列中的01会抵消掉,相当于括号匹配。
给出一段区间,进行2种操作:1、求出区间去掉匹配的01后最大的值(另外给出)。2、修改值。
\(n\leq 100000\ m \leq 100000\)
思路
把01当成括号序列匹配一样进栈,根据此建一棵树。
那么01的序列自然会抵消掉,剩下的查询序列之间就只有3种情况:1111111..000000..11111100000之类
利用树链剖分对树上进行操作。
代码
#include <cstdio>
#include <stdlib.h>
#include <algorithm>
using namespace std;
int n, m, cnt, tot;
int op[100001], a[100001], pos[100001];
int head[100001], ver[200001], next[200001];
int fa[100001], dep[100001], size[100001], son[100001], top[100001], seg[100001];
pair<int, int> v[100001], rev[100001];
void add(int u, int v) {
ver[++tot] = v;
next[tot] = head[u];
head[u] = tot;
}
void dfs1(int u) {
size[u] = 1;
dep[u] = dep[fa[u]] + 1;
for (int i = head[u]; i; i = next[i]) {
if (ver[i] == fa[u]) continue;
dfs1(ver[i]);
size[u] += size[ver[i]];
if (size[ver[i]] > size[son[u]]) son[u] = ver[i];
}
}
void dfs2(int u, int t) {
top[u] = t;
seg[u] = ++cnt;
rev[cnt] = v[u];
if (!son[u]) return;
dfs2(son[u], t);
for (int i = head[u]; i; i = next[i]) {
if (top[ver[i]]) continue;
dfs2(ver[i], ver[i]);
}
}
struct treenode {
int maxv[400001];
void update(int p) {
maxv[p] = max(maxv[p << 1], maxv[p << 1 | 1]);
}
void build(int type, int p, int l, int r) {
if (l == r) {
maxv[p] = type ? rev[l].second : rev[l].first;
return;
}
int mid = l + r >> 1;
build(type, p << 1, l, mid);
build(type, p << 1 | 1, mid + 1, r);
update(p);
}
void modify(int type, int p, int l, int r, int pp, int val) {
if (l == r) {
maxv[p] = val;
type ? rev[l].second = val : rev[l].first = val;
return;
}
int mid = l + r >> 1;
if (pp <= mid) modify(type, p << 1, l, mid, pp, val);
else modify(type, p << 1 | 1, mid + 1, r, pp, val);
update(p);
}
int find(int p, int l, int r, int L, int R) {
if (L <= l && r <= R) return maxv[p];
int res = 0;
int mid = l + r >> 1;
if (L <= mid) res = max(res, find(p << 1, l, mid, L, R));
if (R > mid) res = max(res, find(p << 1 | 1, mid + 1, r, L, R));
return res;
}
}t0, t1;
int query(int type, int x, int y) {
int res = 0;
while (top[x] != top[y]) {
if (dep[top[x]] < dep[top[y]]) swap(x, y), type ^= 1;
res = type ? max(res, t1.find(1, 1, cnt, seg[top[x]], seg[x])) : max(res, t0.find(1, 1, cnt, seg[top[x]], seg[x]));
x = fa[top[x]];
}
if (x == y) return res;
if(dep[x] > dep[y]) swap(x, y);
else type ^= 1;
res = type ? max(res, t1.find(1, 1, cnt, seg[son[x]], seg[y])) : max(res, t0.find(1, 1, cnt, seg[son[x]], seg[y]));
return res;
}
int main() {
int size = 256 << 20;
char *p = (char*) malloc(size) + size;
__asm__("movl %0, %%esp\n" :: "r"(p));
scanf("%d %d", &n, &m);
for (int i = 1; i <= n; i++)
scanf("%d", &op[i]);
for (int i = 1; i <= n; i++)
scanf("%d", &a[i]);
int nn = 1, root = 1, now = 1;
for (int i = 1; i <= n; i++) {
if (!op[i]) {
pos[i] = ++nn;
add(nn, now), add(now, nn);
v[nn].first = a[i];
fa[nn] = now;
now = nn;
} else {
pos[i] = now;
v[now].second = a[i];
if (root == now) {
root = ++nn;
add(now, root), add(root, now);
fa[now] = root;
now = root;
} else now = fa[now];
}
}
dfs1(root);
dfs2(root, root);
t0.build(0, 1, 1, cnt);
t1.build(1, 1, 1, cnt);
for (int x, y, ml; m; m--) {
scanf("%d %d %d", &ml, &x, &y);
if (ml == 1) {
a[x] = y;
op[x] ? t1.modify(1, 1, 1, cnt, seg[pos[x]], y) : t0.modify(1, 1, 1, cnt, seg[pos[x]], y);
} else {
if (x == y) {
printf("%d\n", a[x]);
continue;
}
int px = pos[x], py = pos[y];
if(op[x] == 0) px = fa[px];
if(op[y] == 1) py = fa[py];
printf("%d\n", query(1, px, py));
}
}
}

浙公网安备 33010602011771号