题目链接:https://www.luogu.org/problem/P4116

 

题意:

修改颜色的时候用异或,这里线段树维护的是此区间内第一个出现的黑点。因为是单点修改,所以标记下传啥的都不需要~~直接上区间最值线段树。

如果白点的话就赋值INF,防止参与查询。 

 

树剖后用线段树来维护,维护最小值,黑点的值为𝑑𝑓𝑠序,白点的值为𝐼𝑁𝐹,每次查询找到链上的最小值即为答案。
因为从1到x是一条直链,越上的点也就是越靠近1的点,𝑑𝑓𝑠序一定最小。

 

  1 #include <stdio.h>
  2 #include <cstring>
  3 #include <iostream>
  4 #include <string>
  5 #include <algorithm>
  6 #include <queue>
  7 #include <vector>
  8 #include <math.h>
  9 #include <map>
 10 
 11 #define LL long long
 12 #define INF 0x3f3f3f3f
 13 using namespace std;
 14 const int maxn = 2e5 + 10;
 15 
 16 struct Edge{
 17     int to,next;
 18 }edge[maxn*2];
 19 
 20 int tot,head[maxn];
 21 
 22 void add_edge(int u,int v){
 23     edge[++tot] = Edge{v,head[u]};
 24     head[u] = tot;
 25 }
 26 
 27 int fa[maxn];
 28 int dep[maxn];
 29 int siz[maxn];
 30 int son[maxn];
 31 
 32 void dfs1(int u,int f){
 33     fa[u] = f;
 34     dep[u] = dep[f] + 1;
 35     siz[u] = 1;
 36     int maxsize = -1;
 37     for (int i=head[u];~i;i=edge[i].next){
 38         int v = edge[i].to;
 39         if (v == f)
 40             continue;
 41         dfs1(v,u);
 42         siz[u] += siz[v];
 43         if (siz[v] > maxsize){
 44             son[u] = v;
 45             maxsize = siz[v];
 46         }
 47     }
 48 }
 49 
 50 int tim;
 51 int dfn[maxn];
 52 int w[maxn];
 53 int top[maxn];
 54 
 55 void dfs2(int u,int t){
 56     dfn[u] = ++tim;
 57     top[u] = t;
 58     w[tim] = u;
 59     if (!son[u])
 60         return ;
 61     dfs2(son[u],t);
 62     for (int i=head[u];~i;i=edge[i].next){
 63         int v = edge[i].to;
 64         if (v == fa[u] || v == son[u])
 65             continue;
 66         dfs2(v,v);
 67     }
 68 }
 69 
 70 struct segment_tree{
 71     int l,r;
 72     int val;
 73 }tree[maxn*4];
 74 
 75 void pushup(int nod){
 76     tree[nod].val = min(tree[nod<<1].val,tree[(nod<<1)+1].val);
 77 }
 78 
 79 void build(int l,int r,int nod){
 80     tree[nod].l = l;
 81     tree[nod].r = r;
 82     if (l == r){
 83         tree[nod].val = INF;
 84         return ;
 85     }
 86     int mid = (l + r) >> 1;
 87     build(l,mid,nod<<1);
 88     build(mid+1,r,(nod<<1)+1);
 89     pushup(nod);
 90 }
 91 
 92 void modify(int x,int y,int change,int k=1){
 93     int l = tree[k].l,r = tree[k].r;
 94     if (x <= l && y >= r){
 95         if (change == 1)
 96             tree[k].val = l;
 97         else
 98             tree[k].val = INF;
 99         return ;
100     }
101     int mid = (l + r) >> 1;
102     if (x <= mid){
103         modify(x,y,change,k<<1);
104     }
105     if (y > mid){
106         modify(x,y,change,(k<<1)+1);
107     }
108     pushup(k);
109 }
110 
111 int query(int x,int y,int k=1){
112     int l = tree[k].l,r = tree[k].r;
113     if (x <= l && y >= r){
114         return tree[k].val;
115     }
116     int mid = (l + r) >> 1;
117     int ret = INF;
118     if (x <= mid){
119         ret = min(ret,query(x,y,k<<1));
120     }
121     if (y > mid){
122         ret = min(ret,query(x,y,(k<<1)+1));
123     }
124     return ret;
125 }
126 
127 int query_from(int x,int y){
128     int ret = INF;
129     while (top[x] != top[y]){
130         if (dep[top[x]] < dep[top[y]])
131             swap(x,y);
132         ret = min(ret,query(dfn[top[x]],dfn[x]));
133         x = fa[top[x]];
134     }
135     if (dep[x] > dep[y])
136         swap(x,y);
137     ret = min(ret,query(dfn[x],dfn[y]));
138     return ret;
139 }
140 int color[maxn];
141 int main(){
142     int n,m;
143     scanf("%d%d",&n,&m);
144     memset(head,-1, sizeof(head));
145     for (int i=1;i<=n-1;i++){
146         int x,y;
147         scanf("%d%d",&x,&y);
148         add_edge(x,y);
149         add_edge(y,x);
150     }
151     dfs1(1,0);
152     dfs2(1,1);
153     build(1,n,1);
154     while (m--){
155         int op,x;
156         scanf("%d%d",&op,&x);
157         if (op == 0){
158             color[x] ^= 1;
159             modify(dfn[x],dfn[x],color[x]);
160         }
161         else {
162             int val = query_from(1,x);
163             if (val == INF)
164                 puts("-1");
165             else {
166                 printf("%d\n",w[val]);
167             }
168         }
169     }
170     return 0;
171 }