Interesting, I haven't seen this kind of transform before(it proves that i am remain a newbie).
I try to slove it by using sorts of brute-force seg-tree-update method.
Of course I would get a TLE.
At last, I look for a solution on website as I have thinking about it a whole afternoon.
To my surprise, It's an amazing offline algorithm.
We can transform the tree structure to an array that any subtree is in a continuous interval.
So when staff q is fired, we can find his subordinates with Maximum loyal value in an interval which q's subtree is in.
As to guarantee that his subordinates's ability is higher than him, we sort all staff in descending order according to their ability.
There is. To any specific staff, we can find the one to replace him in advance.
In this case, coding an ordinary RMQ seg-tree is enough.
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <cstring>
#include <string>
#include <vector>
#include <map>
#include <algorithm>
#include <cctype>
#include <queue>
#include <stack>
using namespace std;
#define MS(c, a) memset(c, a, sizeof c)
#define Rep(c, a, b) for (int c = (a); c < (b); c++)
#define Nre(c, a, b) for (int c = (a); c > (b); c--)
#define MAXN (50050)
#define MAXM (1000010)
#define INFI (0x7fffffff)
struct Edge
{
int v, next;
};
vector<Edge> E;
int L[MAXN];
void G_ini()
{
E.clear();
MS(L, -1);
}
void AE(int u, int v)
{
Edge te = {v, L[u]};
L[u] = E.size();
E.push_back(te);
}
struct Stf
{
int sr, ll, ay, l, r;
void inp()
{
scanf("%d%d%d", &sr, &ll, &ay);
}
} s[MAXN];
bool cmp(int p, int q)
{
return s[p].ay > s[q].ay;
}
typedef struct SNode
{
int l, r, m, mx;
SNode *ls, *rs;
SNode()
{
l = r = m = mx = -1;
ls = rs = 0;
}
void set(int _mx)
{
mx = _mx;
}
void upd(SNode *ls, SNode *rs)
{
mx = max(ls->mx, rs->mx);
}
} *PSNode;
SNode St[MAXN << 1], *Stop = St;
struct SGT
{
PSNode rt;
void bui(int l, int r, PSNode x)
{
x->l = l;
x->r = r;
x->m = (l + r) >> 1;
x->set(-1);
if (l == r) return ;
bui(l, x->m, x->ls = ++Stop);
bui(x->m + 1, r, x->rs = ++Stop);
}
void ins(int l, int r, int _mx, PSNode x)
{
if (l <= x->l && x->r <= r) x->set(_mx);
else
{
if (l <= x->m) ins(l, r, _mx, x->ls);
if (x->m < r) ins(l, r, _mx, x->rs);
x->upd(x->ls, x->rs);
}
}
SNode que(int l, int r, PSNode x)
{
SNode res;
if (l <= x->l && x->r <= r) res = *x;
else
{
SNode lre, rre;
if (l <= x->m) lre = que(l, r, x->ls);
if (x->m < r) rre = que(l, r, x->rs);
x->upd(x->ls, x->rs);
res.upd(&lre, &rre);
}
return res;
}
} sgt;
int n, m, id[MAXN], ind, res[MAXM], H[MAXM];
void TTI(int u)
{
s[u].l = ind++;
for (int i = L[u]; i != -1; i = E[i].next) TTI(E[i].v);
s[u].r = ind - 1;
}
int main()
{
int T;
scanf("%d", &T);
while (T--)
{
scanf("%d%d", &n, &m);
G_ini();
MS(H, -1);
Rep(i, 1, n)
{
s[i].inp();
H[s[i].ll] = id[i] = i;
AE(s[i].sr, i);
}
TTI(ind = 0);
sort(id + 1, id + n, cmp);
sgt.bui(0, n - 1, sgt.rt = Stop = St);
for (int i = 1; i < n;)
{
int j;
for (j = i; j < n && s[id[j]].ay == s[id[i]].ay; j++)
{
SNode x;
if (s[id[j]].l < s[id[j]].r)
x = sgt.que(s[id[j]].l + 1, s[id[j]].r, sgt.rt);
res[id[j]] = x.mx < 0? -1: H[x.mx];
}
for (j = i; j < n && s[id[j]].ay == s[id[i]].ay; j++)
sgt.ins(s[id[j]].l, s[id[j]].l, s[id[j]].ll, sgt.rt);
i = j;
}
while (m--)
{
int q;
scanf("%d", &q);
printf("%d\n", res[q]);
}
}
return 0;
}Hoho.
离线算法解决树形结构问题
本文介绍了一种新颖的离线算法,用于解决基于树形结构的更新与查询问题。通过将树形结构转化为数组形式,确保任何子树位于连续区间内,从而能够高效地处理员工解雇及替换问题。文章还详细介绍了使用线段树进行区间最大值查询的具体实现。
1406

被折叠的 条评论
为什么被折叠?



