• 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
    ",w[val]);
    161         }
    162     }
    163     return 0;
    164 }
  • 相关阅读:
    net中System.Security.Cryptography 命名空间 下的加密算法
    关于如何生成代码的帮助文档的链接
    Application.EnableVisualStyles();
    VS2010里属性窗口中的生成操作
    把普通的git库变成bare库
    MultiTouch camera controls source code
    android onTouch()与onTouchEvent()的区别
    iOS开发中常见的语句@synthesize obj = _obj 的意义详解
    java nio 快速read大文件
    使用ndk standalone工具链来编译某个平台下的库
  • 原文地址:https://www.cnblogs.com/-Ackerman/p/11469932.html
Copyright © 2020-2023  润新知