QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#138652 | #5439. Meet in the Middle | savacska | WA | 79ms | 36492kb | C++23 | 4.7kb | 2023-08-12 06:01:59 | 2023-08-12 06:02:00 |
Judging History
answer
#include <bits/stdc++.h>
#define pb push_back
#define mp make_pair
#define x first
#define y second
using namespace std;
typedef long long ll;
typedef long double ld;
const int H = 18;
struct Data
{
pair <int, ll> endA;
pair <int, ll> endB;
ll push;
};
vector <pair <int, int> > treeA[100005], treeB[100005];
int tin[100005], tout[100005];
ll pref_weightA[100005], pref_weightB[100005];
int timer = 0, counter = 0;
int dv[21][100005], order[100005];
pair <int, int> subtree[100005];
Data tree[400005];
vector <pair <int, int> > query[100005];
ll answer[500005];
void calc_dist(int v, int pr)
{
tin[v] = ++timer;
dv[0][v] = pr;
for (int i = 1; i <= H; i++)
if (dv[i - 1][v] != 0) dv[i][v] = dv[i - 1][dv[i - 1][v]];
else break;
for (const auto &[u, w] : treeA[v])
{
if (u == pr) continue;
pref_weightA[u] = pref_weightA[v] + w;
calc_dist(u, v);
}
tout[v] = ++timer;
return;
}
bool is_parent(int a, int b)
{
return tin[a] <= tin[b] && tout[b] <= tout[a];
}
int lca(int a, int b)
{
if (is_parent(a, b)) return a;
if (is_parent(b, a)) return b;
for (int i = H; i >= 0; i--)
if (dv[i][a] != 0 && !is_parent(dv[i][a], b)) a = dv[i][a];
return dv[0][a];
}
ll distanceA(int a, int b)
{
int c = lca(a, b);
return pref_weightA[a] + pref_weightA[b] - 2 * pref_weightA[c];
}
void warmup(int v, int pr)
{
order[++counter] = v;
subtree[v].x = counter;
for (const auto &[u, w] : treeB[v])
{
if (u == pr) continue;
pref_weightB[u] = pref_weightB[v] + w;
warmup(u, v);
}
subtree[v].y = counter;
return;
}
Data merge_info(Data A, Data B)
{
Data res;
res.push = 0;
vector <pair <int, ll> > spis{A.endA, A.endB, B.endA, B.endB};
ll maxim = 0;
for (int i = 0; i < (int) spis.size(); i++)
for (int j = i + 1; j < (int) spis.size(); j++)
{
if (spis[i].x == spis[j].x) continue;
ll len = spis[i].y + spis[j].y + distanceA(spis[i].x, spis[j].x);
if (len > maxim) maxim = len, res.endA = spis[i], res.endB = spis[j];
}
return res;
}
void build_segtree(int v, int lef, int rig)
{
if (lef == rig)
{
tree[v].endA = mp(order[lef], pref_weightB[order[lef]]);
tree[v].endB = mp(order[rig], pref_weightB[order[rig]]);
tree[v].push = 0;
return;
}
int mid = (lef + rig) / 2;
build_segtree(2 * v, lef, mid);
build_segtree(2 * v + 1, mid + 1, rig);
tree[v] = merge_info(tree[2 * v], tree[2 * v + 1]);
return;
}
void full(int v, int lef, int rig, int delta)
{
tree[v].endA.y += delta;
tree[v].endB.y += delta;
tree[v].push += delta;
return;
}
void push(int v, int lef, int rig)
{
int mid = (lef + rig) / 2;
full(2 * v, lef, mid, tree[v].push);
full(2 * v + 1, mid + 1, rig, tree[v].push);
tree[v].push = 0;
return;
}
void update(int v, int lef, int rig, int A, int B, int delta)
{
if (lef > B || rig < A) return;
if (A <= lef && rig <= B)
{
full(v, lef, rig, delta);
return;
}
push(v, lef, rig);
int mid = (lef + rig) / 2;
update(2 * v, lef, mid, A, B, delta);
update(2 * v + 1, mid + 1, rig, A, B, delta);
tree[v] = merge_info(tree[2 * v], tree[2 * v + 1]);
return;
}
void dfsik(int v, int pr, int n)
{
pair <int, ll> endA = tree[1].endA;
pair <int, ll> endB = tree[1].endB;
for (const auto &[u, num] : query[v])
{
//cout << "Query: " << u << ' ' << v << '\n';
ll len1 = endA.y + distanceA(endA.x, u);
ll len2 = endB.y + distanceA(endB.x, u);
//cout << endA.x << ' ' << endA.y << ' ' << len1 << '\n';
//cout << endB.x << ' ' << endB.y << ' ' << len2 << '\n';
answer[num] = max(len1, len2);
}
for (const auto &[u, w] : treeB[v])
{
if (u == pr) continue;
update(1, 1, n, 1, n, w);
update(1, 1, n, subtree[u].x, subtree[u].y, (-2) * w);
dfsik(u, v, n);
update(1, 1, n, subtree[u].x, subtree[u].y, 2 * w);
update(1, 1, n, 1, n, -w);
}
return;
}
int main()
{
//freopen("input.txt", "r", stdin);
//freopen("output.txt", "w", stdout);
ios_base::sync_with_stdio(0); cin.tie(0);
int n, quer;
cin >> n >> quer;
for (int i = 1; i < n; i++)
{
int u, v, w;
cin >> u >> v >> w;
treeA[u].pb(mp(v, w));
treeA[v].pb(mp(u, w));
}
for (int i = 1; i < n; i++)
{
int u, v, w;
cin >> u >> v >> w;
treeB[u].pb(mp(v, w));
treeB[v].pb(mp(u, w));
}
calc_dist(1, 0);
for (int i = 1; i <= quer; i++)
{
int a, b;
cin >> a >> b;
query[b].pb(mp(a, i));
}
warmup(1, -1);
build_segtree(1, 1, n);
dfsik(1, -1, n);
for (int i = 1; i <= quer; i++) cout << answer[i] << '\n';
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 0ms
memory: 32636kb
input:
3 4 1 2 1 2 3 2 1 2 2 2 3 1 1 1 1 2 2 1 2 2
output:
6 4 5 3
result:
ok 4 number(s): "6 4 5 3"
Test #2:
score: 0
Accepted
time: 1ms
memory: 31816kb
input:
2 1 1 2 1 1 2 1 1 1
output:
2
result:
ok 1 number(s): "2"
Test #3:
score: 0
Accepted
time: 0ms
memory: 29756kb
input:
2 1 1 2 1 1 2 1 1 2
output:
1
result:
ok 1 number(s): "1"
Test #4:
score: -100
Wrong Answer
time: 79ms
memory: 36492kb
input:
10000 50000 8101 5996 108427744 5996 7605 870838849 5996 5599 603303696 8101 3006 339377417 8101 6463 442516687 6463 5560 109174079 5560 4063 127596224 3006 1682 947915262 5996 1986 130416311 6463 5455 279771516 6463 2634 516688796 4063 3034 217886863 7605 5092 742375061 5599 2266 193804402 5092 140...
output:
647838384844 798415826648 686149975176 687149190537 644422413068 695925713359 641537859258 745480538428 815957608942 975751484938 674370549986 906640080388 920700079271 939615657346 553499885160 639334376355 786210983344 689550247042 620683131306 898687471632 828971507950 838638025434 863193713645 6...
result:
wrong answer 2nd numbers differ - expected: '626539793176', found: '798415826648'