唐氏求助树剖,思路是白色点是编号 + N,黑点是 i,最后查询最小值。感觉是 SegmentTree 写炸了。。
WA 0pts
#include <bits/stdc++.h>
#define int long long
using namespace std;
struct IO{char buf[1<<20],*p1,*p2;
#define gc()(p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<20,stdin),p1==p2)?EOF:*p1++)
template<typename T>inline T read(T x){T opt=1,sum=0;char ch=gc();while(!isdigit(ch))opt=(ch=='-')?-1:1,ch=gc();while(isdigit(ch))sum=(sum<<1)+(sum<<3)+(ch^48),ch=gc();return opt*sum;}
inline void put(int x){if(x<0){x=-x;putchar('-');}if(x>9)put(x/10);putchar(x%10+48);}}io;
#define read io.read(0ll)
const int N = 1e6;
vector<int> g[N];
int w[N + 5], siz[N + 5], son[N + 5], dep[N + 5], fa[N + 5], _, top[N + 5], a[N + 5], id[N + 5];
struct Segment_Tree
{
struct node
{
int l, r, minn;
}tr[N << 2];
void build(int u, int l, int r)
{
tr[u].l = l, tr[u].r = r;
if(l == r) {
tr[u].minn = a[l];
return ;
}
int mid = (l + r) / 2;
build(u << 1, l, mid), build(u << 1 | 1, mid + 1, r);
tr[u].minn = min(tr[u << 1].minn, tr[u << 1 | 1].minn);
}
void update(int u, int l, int r, int x, int val)
{
if(l == r){
tr[u].minn += val, w[u] += val;
return;
}
int mid = (l + r) / 2;
if(x <= mid) update(u << 1, l, mid, x, val);
else update(u << 1 | 1, mid + 1, r, x, val);
tr[u].minn = min(tr[u << 1].minn, tr[u << 1 | 1].minn);
}
int query(int u, int l, int r)
{
if(l <= tr[u].l && tr[u].r <= r)
{
return tr[u].minn;
}
int mid = (tr[u].l + tr[u].r) / 2;
int res = LONG_LONG_MAX;
if(l <= mid) res = min(res, query(u << 1, l, r));
if(r > mid) res = min(res, query(u << 1 | 1, l, r));
return res;
}
}seg;
void dfs1(int u, int f, int deep)
{
dep[u] = ++deep, fa[u] = f, siz[u] = 1;
int maxn = -1;
for(int i = 0;i < g[u].size();i ++ ){
int v = g[u][i];
if(v == f) continue;
dfs1(v, u, deep + 1);
siz[u] += siz[v];
if(siz[v] > maxn) {
maxn = siz[v];
son[u] = v;
}
}
}
void dfs2(int u, int topf)
{
top[u] = topf;
id[u] = ++_;
a[_] = w[u];
if(!son[u]) return ;
dfs2(son[u], topf);
for(int i = 0;i < g[u].size();i ++ ){
int v = g[u][i];
if(v == fa[u] || v == son[u]) continue;
dfs2(v, v);
}
}
int Query(int x, int y)
{
int ans = LONG_LONG_MAX;
while(top[x] != top[y]){
if(dep[top[x]] < dep[top[y]]) swap(x, y);
ans = min(ans, seg.query(1, id[top[x]], id[x]));
x = fa[top[x]];
}
if(dep[x] > dep[y]) swap(x, y);
ans = min(ans, seg.query(1, id[x], id[y]));
return ans;
}
signed main()
{
int n = read, q = read;
for(int i = 1;i < n;i ++ ) {
int a = read, b = read; g[a].push_back(b), g[b].push_back(a);
}
for(int i = 1;i <= n;i ++ ) w[i] = i + N;
dfs1(1, 0, 1);
dfs2(1, 1);
seg.build(1, 1, n);
while(q -- )
{
int op = read, v = read;
if(op == 0){
if(w[v] > N) seg.update(1, 1, n, id[v], -N);
else seg.update(1, 1, n, id[v], N);
}
else {
int ans = Query(1, v);
if(ans > N || ans < 0) cout << -1 << endl;
else cout << ans << endl;
}
// for(int i = 1;i <= n;i ++ ) cout << w[i] << ' ';
// cout << endl;
}
return 0;
}