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 }