P4092 [HEOI2016/TJOI2016]树

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

 

感觉这个题目和前面做的黑白染色的很像,思路都是差不多的吧。

 

  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 = max(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 = 1;
 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 k=1){
 93     int l = tree[k].l,r = tree[k].r;
 94     if (x <= l && y >= r){
 95         tree[k].val = l;
 96         return ;
 97     }
 98     int mid = (l + r) >> 1;
 99     if (x <= mid){
100         modify(x,y,k<<1);
101     }
102     if (y > mid){
103         modify(x,y,(k<<1)+1);
104     }
105     pushup(k);
106 }
107 
108 int query(int x,int y,int k=1){
109     int l = tree[k].l,r = tree[k].r;
110     if (x <= l && y >= r){
111         return tree[k].val;
112     }
113     int mid = (l + r) >> 1;
114     int ret = 0;
115     if (x <= mid){
116         ret = max(ret,query(x,y,k<<1));
117     }
118     if (y > mid){
119         ret = max(ret,query(x,y,(k<<1)+1));
120     }
121     return ret;
122 }
123 
124 int query_from(int x,int y){
125     int ret = 0;
126     while (top[x] != top[y]){
127         if (dep[top[x]] < dep[top[y]])
128             swap(x,y);
129         ret = max(ret,query(dfn[top[x]],dfn[x]));
130         x = fa[top[x]];
131     }
132     if (dep[x] > dep[y])
133         swap(x,y);
134     ret = max(ret,query(dfn[x],dfn[y]));
135     return ret;
136 }
137 
138 int main(){
139     int n,m;
140     scanf("%d%d",&n,&m);
141     memset(head,-1, sizeof(head));
142     for (int i=1;i<=n-1;i++){
143         int x,y;
144         scanf("%d%d",&x,&y);
145         add_edge(x,y);
146         add_edge(y,x);
147     }
148     dfs1(1,0);
149     dfs2(1,1);
150     build(1,n,1);
151     while (m--){
152         int x;
153         char op[4];
154         scanf("%s%d",op,&x);
155         if (op[0] == 'C'){
156             modify(dfn[x],dfn[x]);
157         }
158         else {
159             int val = query_from(1,x);
160             printf("%d\n",w[val]);
161         }
162     }
163     return 0;
164 }

 

posted @ 2019-09-05 21:31  _Ackerman  阅读(212)  评论(0编辑  收藏  举报