P4092 [HEOI2016/TJOI2016]树

Posted -ackerman

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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] = Edgev,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 

 

以上是关于P4092 [HEOI2016/TJOI2016]树的主要内容,如果未能解决你的问题,请参考以下文章

luogu题解 P4092 [HEOI2016/TJOI2016]树树链剖分

[HEOI2016/TJOI2016]排序

P4093[HEOI2016/TJOI2016]序列

[HEOI2016/TJOI2016]求和

[HEOI2016/TJOI2016]排序 解题报告

[HEOI2016/TJOI2016]求和