QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#695087 | #5439. Meet in the Middle | raywu | RE | 0ms | 0kb | C++14 | 6.1kb | 2024-10-31 19:18:15 | 2024-10-31 19:18:15 |
answer
#include <bits/stdc++.h>
#define _for(i, a, b) for (int i = (a); i <= (b); i ++ )
#define mp make_pair
#define pb push_back
#define F first
#define S second
#define P pair<int, int>
#define ll long long
using namespace std;
const int N = 1e5 + 5, M = 5e5 + 5;
int n, q; ll x, ans[M]; vector<P > qry[N];
namespace IO {
static char buf[1000000], * p1 = buf, * p2 = buf, obuf[1000000], * p3 = obuf, cc[20];
#define gc() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, N - 5, stdin), p1 == p2) ? EOF : * p1 ++ )
#define pc(x) (p3 - obuf < 1000000) ? ( * p3 ++ = x) : (fwrite(obuf, p3 - obuf, 1, stdout), p3 = obuf, * p3 ++ = x)
inline int rd() {
int val = 0, sgn = 1; char ch = gc();
while (! isdigit(ch)) { if (ch == '-') sgn = -1; ch = gc(); }
while (isdigit(ch)) val = (val << 3) + (val << 1) + (ch ^ 48), ch = gc();
return (val * sgn);
}
template <typename item>
inline void print(item x){
if (! x) pc('0');
int len = 0;
if (x < 0) x = - x, pc('-');
while (x) cc[len ++ ] = x % 10 | '0', x /= 10;
while (len -- ) pc(cc[len]);
}
inline void write(long long x, char c) { print(x), pc(c); }
} using namespace IO;
struct Tree {
int dfn_cnt, timer, sz[N], son[N], fa[N], dep[N], top[N], rk[N], dfn[N], pos[N], Log[N << 1], a[N << 1], ST[N << 1][20]; ll dis[N]; vector<P > G[N];
inline void clear() {
dfn_cnt = timer = 0;
_for (i, 1, n) dfn[i] = dis[i] = dep[i] = 0, G[i].clear();
}
void dfs1(int u) {
sz[u] = 1, son[u] = - 1, a[pos[u] = ++ timer] = u;
for (P v : G[u]) if (v.F ^ fa[u]) {
dep[v.F] = dep[u] + 1, dis[v.F] = dis[u] + v.S, fa[v.F] = u, dfs1(v.F), sz[u] += sz[v.F], a[ ++ timer] = u;
if (son[u] == - 1 || sz[son[u]] < sz[v.F]) son[u] = v.F;
}
}
void dfs2(int u, int Top) {
top[u] = Top, rk[dfn[u] = ++ dfn_cnt] = u;
if (son[u] == - 1) return ;
dfs2(son[u], Top);
for (P v : G[u]) if (v.F ^ fa[u] && v.F ^ son[u]) dfs2(v.F, v.F);
}
inline int lca(int u, int v) {
int U = top[u], V = top[v];
while (U ^ V) {
if (dep[U] >= dep[V]) u = fa[U];
else v = fa[V];
U = top[u], V = top[v];
}
return (dep[u] < dep[v] ? u : v);
}
inline void pre_work() {
Log[0] = - 1;
_for (i, 1, n << 1) Log[i] = Log[i >> 1] + 1;
_for (i, 1, n << 1) ST[i][0] = a[i];
_for (j, 1, Log[n << 1]) _for (i, 1, (n << 1) - (1 << j) + 1) ST[i][j] = dep[ST[i][j - 1]] < dep[ST[i + (1 << (j - 1))][j - 1]] ? ST[i][j - 1] : ST[i + (1 << (j - 1))][j - 1];
}
inline int query(int u, int v) {
int l = pos[u], r = pos[v];
if (l > r) l ^= r ^= l ^= r;
int k = Log[r - l + 1];
return dep[ST[l][k]] < dep[ST[r - (1 << k) + 1][k]] ? ST[l][k] : ST[r - (1 << k) + 1][k];
}
inline ll dist(int u, int v) { return dis[u] + dis[v] - 2ll * dis[query(u, v)]; }
} T[2];
struct Seg_Tree {
#define lc (p << 1)
#define rc (p << 1 | 1)
#define mid ((tr[p].l + tr[p].r) >> 1)
struct Tree { int l, r, A, B; ll tag, dis, val_A, val_B; } res, tr[N << 2];
inline int len(int p) { return tr[p].r - tr[p].l + 1; }
inline bool In(int p, int l, int r) { return l <= tr[p].l && tr[p].r <= r; }
inline void push_tag(int p, ll k) { tr[p].tag += k, tr[p].val_A += k, tr[p].val_B += k; }
inline Tree merge(Tree u, Tree v) {
res.l = u.l, res.r = v.r, res.dis = 0;
if ((x = T[1].dist(u.A, u.B) + u.val_A + u.val_B) > res.dis) res.dis = x, res.A = u.A, res.B = u.B, res.val_A = u.val_A, res.val_B = u.val_B;
if ((x = T[1].dist(u.A, v.B) + u.val_A + v.val_B) > res.dis) res.dis = x, res.A = u.A, res.B = v.B, res.val_A = u.val_A, res.val_B = v.val_B;
if ((x = T[1].dist(v.A, u.B) + v.val_A + u.val_B) > res.dis) res.dis = x, res.A = v.A, res.B = u.B, res.val_A = v.val_A, res.val_B = u.val_B;
if ((x = T[1].dist(v.A, v.B) + v.val_A + v.val_B) > res.dis) res.dis = x, res.A = v.A, res.B = v.B, res.val_A = v.val_A, res.val_B = v.val_B;
if ((x = T[1].dist(u.A, v.A) + u.val_A + v.val_A) > res.dis) res.dis = x, res.A = u.A, res.B = v.A, res.val_A = u.val_A, res.val_B = v.val_A;
if ((x = T[1].dist(u.B, v.B) + u.val_B + v.val_B) > res.dis) res.dis = x, res.A = u.B, res.B = v.B, res.val_A = u.val_B, res.val_B = v.val_B;
return res;
}
inline void push_down(int p) { if (tr[p].tag) push_tag(lc, tr[p].tag), push_tag(rc, tr[p].tag), tr[p].tag = 0; }
void build(int p, int l, int r) {
tr[p].l = l, tr[p].r = r, tr[p].tag = 0;
if (l == r) { tr[p].A = tr[p].B = T[0].rk[l], tr[p].dis = 0, tr[p].val_A = tr[p].val_B = T[0].dis[T[0].rk[l]]; return ; }
build(lc, l, mid), build(rc, mid + 1, r), tr[p] = merge(tr[lc], tr[rc]);
}
void update(int p, int l, int r, ll k) {
if (In(p, l, r)) { push_tag(p, k); return ; }
push_down(p);
if (l <= mid) update(lc, l, r, k);
if (r > mid) update(rc, l, r, k);
tr[p] = merge(tr[lc], tr[rc]);
}
Tree query(int p, int l, int r) {
if (In(p, l, r)) return tr[p];
push_down(p);
if (r <= mid) return query(lc, l, r);
if (l > mid) return query(rc, l, r);
return merge(query(lc, l, r), query(rc, l, r));
}
#undef lc
#undef rc
#undef mid
} SGT;
void dfs3(int u) {
Seg_Tree :: Tree tr = SGT.query(1, 1, n); int A = tr.A, B = tr.B; ll x, y, val_A = tr.val_A, val_B = tr.val_B;
for (P v : qry[u]) x = T[1].dist(v.F, A), y = T[1].dist(v.F, B), ans[v.S] = max(x + val_A, y + val_B);
for (P v : T[0].G[u]) if (v.F ^ T[0].fa[u]) SGT.update(1, 1, n, v.S), SGT.update(1, T[0].dfn[v.F], T[0].dfn[v.F] + T[0].sz[v.F] - 1, - 2ll * v.S), dfs3(v.F), SGT.update(1, 1, n, - v.S), SGT.update(1, T[0].dfn[v.F], T[0].dfn[v.F] + T[0].sz[v.F] - 1, 2ll * v.S);
}
inline void solve() {
n = rd(), T[0].clear(), T[1].clear(); int u, v, w;
_for (i, 1, n) qry[i].clear();
_for (o, 0, 1) _for (i, 2, n) u = rd(), v = rd(), w = rd(), T[o].G[u].pb(mp(v, w)), T[o].G[v].pb(mp(u, w));
_for (o, 0, 1) T[o].dfs1(1), T[o].dfs2(1, 1), T[o].pre_work();
SGT.build(1, 1, n), q = rd();
_for (i, 1, q) u = rd(), v = rd(), qry[u].push_back(mp(v, i));
_for (i, 1, n) sort(qry[i].begin(), qry[i].end());
dfs3(1);
_for (i, 1, q) write(ans[i], '\n');
}
int main() {
ios :: sync_with_stdio(false), cin.tie(0), cout.tie(0);
int T = rd();
while (T -- ) solve();
fwrite(obuf, p3 - obuf, 1, stdout);
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 0
Runtime Error
input:
3 4 1 2 1 2 3 2 1 2 2 2 3 1 1 1 1 2 2 1 2 2