https://codeforces.com/contest/1413/submission/257729948
// Problem: CF1413F Roads and Ramen
// Memory Limit: 500 MB
// Time Limit: 5000 ms
#include <bits/stdc++.h>
#define int long long
#define min(x,y) (((x)<(y))?(x):(y))
#define max(x,y) (((x)>(y))?(x):(y))
#define lowbit(x) ((x)&-(x))
#define abs(x) (((x)<(0))?(-(x)):(x))
#define swap(a,b) a^=b^=a^=b
#define INF 1e18
#define MAXN 2000000
using namespace std;
int n, m, x[MAXN], y[MAXN], z, k, root1, root2, rt1, rt2, nowtree;
vector<pair<int,int> > e[MAXN];
int fa[MAXN], de[MAXN], dfn[MAXN], bgn[MAXN], ending[MAXN], xs[MAXN], len[MAXN];
int fa1[MAXN], de1[MAXN], dfn1[MAXN], bgn1[MAXN], end1[MAXN], xs1[MAXN], len1[MAXN];
int fa2[MAXN], de2[MAXN], dfn2[MAXN], bgn2[MAXN], end2[MAXN], xs2[MAXN], len2[MAXN];
int dfsdeepest(int id, int nowde, int nowxs)
{
de[id] = nowde;
xs[id] = nowxs;
dfn[++dfn[0]] = id;
bgn[id] = dfn[0];
int ans = id;
for (pair<int, int> i : e[id])
{
if (de[i.first])
{
continue;
}
fa[i.first] = id;
len[i.first] = i.second;
int sonans = dfsdeepest(i.first, nowde + 1, nowxs ^ i.second);
if (de[sonans] > nowde)
{
ans = sonans;
}
}
ending[id] = dfn[0];
return ans;
}
struct segment_tree
{
int tag0[MAXN], tag1[MAXN], tag[MAXN];
void flap(int id)
{
swap(tag0[id], tag1[id]);
tag[id] ^= 1;
}
void pushdown(int id)
{
if (tag[id])
{
flap(id * 2);
flap(id * 2 + 1);
tag[id] = 0;
}
}
void build(int id, int l, int r)
{
if (l == r)
{
int realid, realde, realxs;
if (nowtree == 1)
{
realid = dfn1[l];
realde = de1[realid];
realxs = xs1[realid];
}
if (nowtree == 2)
{
realid = dfn2[l];
realde = de2[realid];
realxs = xs2[realid];
}
if (realxs == 0)
{
tag0[id] = realde;
}
if (realxs == 1)
{
tag1[id] = realde;
}
// cout << "build " << nowtree << " " << id << " " << l << " " << r << " "
// << realid << " " << realde << " " << realxs << endl;
return;
}
int mid = (l + r) / 2;
build(id * 2, l, mid);
build(id * 2 + 1, mid + 1, r);
tag0[id] = max(tag0[id * 2], tag0[id * 2 + 1]);
tag1[id] = max(tag1[id * 2], tag1[id * 2 + 1]);
}
// void print(int id, int l, int r)
// {
// cout << "print " << id << " " << l << " " << r << " "
// << tag0[id] << " " << tag1[id] << " " << tag[id] << endl;
// if (l == r)
// {
// return;
// }
// int mid = (l + r) / 2;
// print(id * 2, l, mid);
// print(id * 2 + 1, mid + 1, r);
// }
void update(int id, int l, int r, int x, int y)
{
if (x > y || x > r || y < l)
{
return;
}
if (l == r)
{
flap(id);
return;
}
pushdown(id);
int mid = (l + r) / 2;
update(id * 2, l, mid, x, min(mid, y));
update(id * 2 + 1, mid + 1, r, max(x, mid + 1), y);
tag0[id] = max(tag0[id * 2], tag0[id * 2 + 1]);
tag1[id] = max(tag1[id * 2], tag1[id * 2 + 1]);
}
} tree1, tree2;
signed main()
{
cin >> n;
for (int i = 1; i < n; i++)
{
cin >> x[i] >> y[i] >> k;
e[x[i]].push_back({y[i], k});
e[y[i]].push_back({x[i], k});
}
root1 = dfsdeepest(1, 1, 0);
memset(fa, 0, sizeof(fa));
memset(de, 0, sizeof(de));
memset(dfn, 0, sizeof(dfn));
memset(bgn, 0, sizeof(bgn));
memset(ending, 0, sizeof(ending));
memset(xs, 0, sizeof(xs));
memset(len, 0, sizeof(len));
root2 = dfsdeepest(root1, 1, 0);
for (int i = 1; i <= n; i++)
{
fa1[i] = fa[i];
de1[i] = de[i];
dfn1[i] = dfn[i];
bgn1[i] = bgn[i];
end1[i] = ending[i];
xs1[i] = xs[i];
len1[i] = len[i];
}
memset(fa, 0, sizeof(fa));
memset(de, 0, sizeof(de));
memset(dfn, 0, sizeof(dfn));
memset(bgn, 0, sizeof(bgn));
memset(ending, 0, sizeof(ending));
memset(xs, 0, sizeof(xs));
memset(len, 0, sizeof(len));
dfsdeepest(root2, 1, 0);
for (int i = 1; i <= n; i++)
{
fa2[i] = fa[i];
de2[i] = de[i];
dfn2[i] = dfn[i];
bgn2[i] = bgn[i];
end2[i] = ending[i];
xs2[i] = xs[i];
len2[i] = len[i];
}
nowtree = 1;
tree1.build(1, 1, n);
nowtree = 2;
tree2.build(1, 1, n);
nowtree = 0;
// cout << "root1 " << root1 << endl;
// cout << "fa1:\t";
// for (int i = 1; i <= n; i++)
// {
// cout << fa1[i] << " ";
// }
// cout << endl;
// cout << "de1:\t";
// for (int i = 1; i <= n; i++)
// {
// cout << de1[i] << " ";
// }
// cout << endl;
// cout << "dfn1:\t";
// for (int i = 1; i <= n; i++)
// {
// cout << dfn1[i] << " ";
// }
// cout << endl;
// cout << "bgn1:\t";
// for (int i = 1; i <= n; i++)
// {
// cout << bgn1[i] << " ";
// }
// cout << endl;
// cout << "end1:\t";
// for (int i = 1; i <= n; i++)
// {
// cout << end1[i] << " ";
// }
// cout << endl;
// cout << "xs1:\t";
// for (int i = 1; i <= n; i++)
// {
// cout << xs1[i] << " ";
// }
// cout << endl;
// cout << "len1:\t";
// for (int i = 1; i <= n; i++)
// {
// cout << len1[i] << " ";
// }
// cout << endl;
// cout << "root2 " << root2 << endl;
// cout << "fa2:\t";
// for (int i = 1; i <= n; i++)
// {
// cout << fa2[i] << " ";
// }
// cout << endl;
// cout << "de2:\t";
// for (int i = 1; i <= n; i++)
// {
// cout << de2[i] << " ";
// }
// cout << endl;
// cout << "dfn2:\t";
// for (int i = 1; i <= n; i++)
// {
// cout << dfn2[i] << " ";
// }
// cout << endl;
// cout << "bgn2:\t";
// for (int i = 1; i <= n; i++)
// {
// cout << bgn2[i] << " ";
// }
// cout << endl;
// cout << "end2:\t";
// for (int i = 1; i <= n; i++)
// {
// cout << end2[i] << " ";
// }
// cout << endl;
// cout << "xs2:\t";
// for (int i = 1; i <= n; i++)
// {
// cout << xs2[i] << " ";
// }
// cout << endl;
// cout << "len2:\t";
// for (int i = 1; i <= n; i++)
// {
// cout << len2[i] << " ";
// }
// cout << endl;
// cout << "tree1.print:\n";
// tree1.print(1, 1, n);
// cout << "tree2.print:\n";
// tree2.print(1, 1, n);
cin >> m;
while (m--)
{
cin >> k;
if (fa1[x[k]] == y[k])
{
rt1 = x[k];
}
else
{
rt1 = y[k];
}
if (fa2[x[k]] == y[k])
{
rt2 = x[k];
}
else
{
rt2 = y[k];
}
// cout << "rt1 = " << rt1 << " rt2 = " << rt2 << endl;
tree1.update(1, 1, n, bgn1[rt1], end1[rt1]);
tree2.update(1, 1, n, bgn2[rt2], end2[rt2]);
tree1.pushdown(1);
tree2.pushdown(1);
// cout << bgn1[rt1] << " " << end1[rt1] << endl;
// cout << bgn2[rt2] << " " << end2[rt2] << endl;
// cout << "tree1.print:\n";
// tree1.print(1, 1, n);
// cout << "tree2.print:\n";
// tree2.print(1, 1, n);
// cout << tree1.tag0[1] << " " << tree2.tag0[1] << endl;
cout << max(tree1.tag0[1], tree2.tag0[1]) - 1 << endl;
}
return 0;
}