QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#138646 | #5439. Meet in the Middle | savacska | WA | 93ms | 39540kb | C++23 | 4.6kb | 2023-08-12 05:39:52 | 2023-08-12 05:39:55 |
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 << u << ' ' << v << '\n';
ll len1 = endA.y + distanceA(endA.x, u);
ll len2 = endB.y + distanceA(endB.x, u);
//cout << endA.x << ' ' << len1 << '\n';
//cout << endB.x << ' ' << 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[v].x + 1, subtree[v].y, (-2) * w);
dfsik(u, v, n);
update(1, 1, n, subtree[v].x + 1, subtree[v].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: 1ms
memory: 32776kb
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: 3ms
memory: 31556kb
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: 5ms
memory: 33088kb
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: 93ms
memory: 39540kb
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:
645994505608 798373057552 686107206080 685598868285 644379643972 694375391107 639693980022 745437769332 815914839846 975708715842 672526670750 906597311292 920657310175 939572888250 551656005924 638704517941 786168214248 687706367806 618994691732 898644702536 828928738854 838595256338 863150944549 6...
result:
wrong answer 1st numbers differ - expected: '647838384844', found: '645994505608'