题解 CF1062E 【Company】
md真降智了……删dfn最小或最大的点就行了……
那我就来个数据结构学傻了的代码6个多K的辣鸡做法吧……
首先,我们可以知道
考虑上述操作怎么实现,首先我们可以用线段树合并知道子树内
上代码~(格式化后有10K……)
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize("Ofast")
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
#define N 100011
#define ls(_o) (_o << 1)
#define rs(_o) ((_o << 1) | 1)
using namespace std;
namespace ywy {
inline int get() {
int n = 0;
char c;
while ((c = getchar()) || 23333) {
if (c >= '0' && c <= '9')
break;
if (c == '-')
goto s;
}
n = c - '0';
while ((c = getchar()) || 23333) {
if (c >= '0' && c <= '9')
n = n * 10 + c - '0';
else
return (n);
}
s:
while ((c = getchar()) || 23333) {
if (c >= '0' && c <= '9')
n = n * 10 - c + '0';
else
return (n);
}
}
typedef struct _b {
int dest;
int nxt;
} bian;
bian memchi[1000001];
int gn = 1, heads[N], dfn[N], fan[N], size[N], zhongson[N], st[N * 2][18], lg[N * 2], gdfn = 1;
inline void add(int s, int t) {
memchi[gn].dest = t;
memchi[gn].nxt = heads[s];
heads[s] = gn;
gn++;
}
int early[N], late[N], top[N], gstp = 1, rt[N], lef[10000001], rgh[10000001], data[10000001], gseg = 1;
inline int lca(int a, int b) {
if (!(a && b))
return (a | b);
if (dfn[a] > dfn[b])
swap(a, b);
a = early[a];
b = late[b];
int g = lg[b - a + 1];
return (fan[min(st[a][g], st[b - (1 << g) + 1][g])]);
}
int lcas[1000001];
void build(int l, int r, int tree) {
if (l == r) {
lcas[tree] = l;
return;
}
int mid = (l + r) >> 1;
build(l, mid, ls(tree));
build(mid + 1, r, rs(tree));
lcas[tree] = lca(lcas[ls(tree)], lcas[rs(tree)]);
}
int query(int rl, int rr, int l, int r, int tree) {
if (rl > rr)
return (0);
if (rl == l && rr == r)
return (lcas[tree]);
int mid = (l + r) >> 1;
if (rl > mid)
return (query(rl, rr, mid + 1, r, rs(tree)));
if (rr <= mid)
return (query(rl, rr, l, mid, ls(tree)));
return (lca(query(rl, mid, l, mid, ls(tree)), query(mid + 1, rr, mid + 1, r, rs(tree))));
}
void insert(int l, int r, int &tree, int pt) {
if (!tree)
tree = gseg, gseg++;
data[tree]++;
if (l == r)
return;
int mid = (l + r) >> 1;
if (pt <= mid)
insert(l, mid, lef[tree], pt);
else
insert(mid + 1, r, rgh[tree], pt);
}
int qdat(int rl, int rr, int l, int r, int tree) {
if (!data[tree])
return (0);
if (rl == l && rr == r)
return (data[tree]);
int mid = (l + r) >> 1;
if (rl > mid)
return (qdat(rl, rr, mid + 1, r, rgh[tree]));
if (rr <= mid)
return (qdat(rl, rr, l, mid, lef[tree]));
return (qdat(rl, mid, l, mid, lef[tree]) + qdat(mid + 1, rr, mid + 1, r, rgh[tree]));
}
int united(int a, int b) {
if (!(a && b))
return (a | b);
int me = gseg;
gseg++;
data[me] = data[a] + data[b];
lef[me] = united(lef[a], lef[b]);
rgh[me] = united(rgh[a], rgh[b]);
return (me);
}
int qfirst(int rl, int rr, int l, int r, int tree) {
if (!data[tree])
return (0);
if (l == r)
return (l);
int mid = (l + r) >> 1;
if (rl == l && rr == r) {
if (data[lef[tree]])
return (qfirst(l, mid, l, mid, lef[tree]));
return (qfirst(mid + 1, r, mid + 1, r, rgh[tree]));
}
if (rl > mid)
return (qfirst(rl, rr, mid + 1, r, rgh[tree]));
if (rr <= mid)
return (qfirst(rl, rr, l, mid, lef[tree]));
int cjr = qfirst(rl, mid, l, mid, lef[tree]);
if (cjr)
return (cjr);
return (qfirst(mid + 1, rr, mid + 1, r, rgh[tree]));
}
typedef struct _p {
int a;
int b;
_p(int i, int j) {
a = i;
b = j;
}
friend bool operator<(const _p &a, const _p &b) {
if (a.b != b.b)
return (a.b < b.b);
return (a.a < b.a);
}
friend bool operator==(const _p &a, const _p &b) { return (a.a == b.a && a.b == b.b); }
} pair;
typedef struct _heap {
priority_queue<pair> me, del;
inline void wh() {
while (!me.empty() && !del.empty() && me.top() == del.top()) me.pop(), del.pop();
}
inline void push(pair x) { me.push(x); }
inline int size() { return (me.size() - del.size()); }
inline pair top() {
wh();
return (me.top());
}
inline void erase(pair x) { del.push(x); }
inline void pop() {
wh();
me.pop();
}
} heap;
heap chs[100001];
int n;
int deep[N];
int lst[N], fa[N];
void dfs(int pt, int baba) {
size[pt] = 1;
int mx = 0, best = 0;
for (register int i = heads[pt]; i; i = memchi[i].nxt) {
if (memchi[i].dest == baba)
continue;
deep[memchi[i].dest] = deep[pt] + 1;
dfs(memchi[i].dest, pt);
size[pt] += size[memchi[i].dest];
rt[pt] = united(rt[pt], rt[memchi[i].dest]);
if (size[memchi[i].dest] > mx)
mx = size[memchi[i].dest], best = memchi[i].dest;
}
insert(1, n, rt[pt], pt);
top[pt] = pt;
zhongson[pt] = best;
lst[pt] = -1;
}
int anspt[N], anss[N];
void efs(int pt, int baba) {
if (zhongson[pt])
top[zhongson[pt]] = top[pt], efs(zhongson[pt], pt);
for (register int i = heads[pt]; i; i = memchi[i].nxt) {
if (memchi[i].dest == baba || zhongson[pt] == memchi[i].dest)
continue;
efs(memchi[i].dest, pt);
}
}
vector<pair> vec[N]; // a->l,b->id
void ffs(int pt, int baba) {
dfn[pt] = gdfn;
fan[gdfn] = pt;
gdfn++;
st[gstp][0] = dfn[pt];
gstp++;
early[pt] = late[pt] = gstp - 1;
for (register int i = heads[pt]; i; i = memchi[i].nxt) {
if (memchi[i].dest == baba)
continue;
ffs(memchi[i].dest, pt);
st[gstp][0] = dfn[pt];
late[pt] = gstp;
gstp++;
}
}
inline int calc(int l, int r, int x) { return (lca(query(l, x - 1, 1, n, 1), query(x + 1, r, 1, n, 1))); }
vector<int> tmp;
inline void clear(vector<int> &v) {
vector<int> ff;
v = ff;
}
void ywymain() {
n = get();
int q = get();
for (register int i = 2; i <= n; i++) add(fa[i] = get(), i);
ffs(1, 0);
gstp--;
lg[0] = -1;
for (register int i = 1; i <= gstp; i++) lg[i] = lg[i - 1] + (i == (i & -i));
for (register int i = 1; i <= lg[gstp]; i++) {
for (register int j = 1; j <= gstp - (1 << i) + 1; j++)
st[j][i] = min(st[j][i - 1], st[j + (1 << (i - 1))][i - 1]);
}
build(1, n, 1);
dfs(1, 0);
efs(1, 0);
for (register int i = 1; i <= q; i++) {
int l = get(), r = get();
vec[r].push_back(_p(l, i));
}
for (register int i = 1; i <= n; i++) {
int cur = top[i];
while (fa[cur]) {
if (lst[cur] != -1)
chs[fa[cur]].erase(_p(cur, lst[cur]));
chs[fa[cur]].push(_p(cur, lst[cur] = i));
cur = top[fa[cur]];
}
for (register int j = 0; j < vec[i].size(); j++) {
int ance = query(vec[i][j].a, i, 1, n, 1);
if (ance >= vec[i][j].a && ance <= i) {
anspt[vec[i][j].b] = ance;
anss[vec[i][j].b] = deep[calc(vec[i][j].a, i, ance)];
continue;
}
clear(tmp);
if (zhongson[ance]) {
if (qdat(vec[i][j].a, i, 1, n, rt[zhongson[ance]]))
tmp.push_back(zhongson[ance]);
}
if (chs[ance].size() >= 1) {
pair cjr = chs[ance].top();
chs[ance].pop();
if (cjr.b >= vec[i][j].a) {
tmp.push_back(cjr.a);
if (chs[ance].size() >= 1) {
pair a = chs[ance].top();
chs[ance].pop();
if (a.b >= vec[i][j].a) {
tmp.push_back(a.a);
if (chs[ance].size() >= 1) {
pair b = chs[ance].top();
chs[ance].pop();
if (b.b >= vec[i][j].a) {
tmp.push_back(b.a);
}
chs[ance].push(b);
}
}
chs[ance].push(a);
}
}
chs[ance].push(cjr);
}
if (tmp.size() >= 3) {
anss[vec[i][j].b] = deep[ance];
anspt[vec[i][j].b] = i;
continue;
}
anspt[vec[i][j].b] = i;
anss[vec[i][j].b] = deep[ance];
for (register int k = 0; k < 2; k++) {
if (qdat(vec[i][j].a, i, 1, n, rt[tmp[k]]) == 1) {
int best = qfirst(vec[i][j].a, i, 1, n, rt[tmp[k]]),
res = deep[calc(vec[i][j].a, i, best)];
if (res > anss[vec[i][j].b])
anss[vec[i][j].b] = res, anspt[vec[i][j].b] = best;
}
}
}
}
for (register int i = 1; i <= q; i++) printf("%d %d\n", anspt[i], anss[i]);
}
}
int main() {
ywy::ywymain();
return (0);
}