zoukankan      html  css  js  c++  java
  • HDU5266---pog loves szh III (线段树+LCA)

    题意:N个点的有向树, Q次询问, 每次询问区间[L, R]内所有点的LCA。

    大致做法:线段树每个点保存它的孩子的LCA值, 对于每一次询问只需要 在线段树查询即可。

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 const int MAXN = 3e5+10;
      4 struct Edge{
      5     int to, next;
      6 }e[MAXN << 1];
      7 int head[MAXN], tot_edge;
      8 void Add_Edge (int x, int y){
      9     e[tot_edge].to = y;
     10     e[tot_edge].next = head[x];
     11     head[x] = tot_edge++;
     12 }
     13 int n, q, MAX_LOG_V;
     14 bool vis[MAXN];
     15 void init (){
     16     MAX_LOG_V = 20;
     17     tot_edge = 0;
     18     memset(head, -1, sizeof (head));
     19     memset(vis, false, sizeof (vis));
     20 }
     21 int dep[MAXN], pa[25][MAXN];
     22 void DFS (int r, int pre, int d){                    // DFS 或 BFS都可以, G++下BFS
     23     dep[r] = d;
     24     pa[0][r] = pre;
     25     for (int i = head[r]; ~i; i = e[i].next){
     26         int u = e[i].to;
     27         if (pre != u){
     28             DFS(u, r, d+1);
     29         }
     30     }
     31 }
     32 void BFS (int r, int pre, int d){
     33     dep[r] = d;
     34     pa[0][r] = pre;
     35     queue <int>Q;
     36     Q.push(r);
     37     vis[r] = true;
     38     while (!Q.empty()){
     39         int u = Q.front();
     40         Q.pop();
     41         for (int i = head[u]; ~i; i = e[i].next){
     42             int v = e[i].to;
     43             if (!vis[v]){
     44                 dep[v] = dep[u] + 1;
     45                 pa[0][v] = u;
     46                 Q.push(v);
     47                 vis[v] = true;
     48             }
     49         }
     50     }
     51 }
     52 void pre_solve (){
     53     BFS(1, -1, 0);
     54     for (int k = 0; k + 1 < MAX_LOG_V; k++){
     55         for (int v = 1; v <= n; v++){
     56             if (pa[k][v] < 0){
     57                 pa[k+1][v] = -1;
     58             }else{
     59                 pa[k+1][v] = pa[k][pa[k][v]];
     60             }
     61         }
     62     }
     63 }
     64 int LCA (int u, int v){
     65     if (dep[u] > dep[v]){
     66         swap(u, v);
     67     }
     68     for (int k = 0; k < MAX_LOG_V; k++){
     69         if ((dep[v] - dep[u]) >> k & 1){
     70             v = pa[k][v];
     71         }
     72     }
     73     if (u == v){
     74         return u;
     75     }
     76     for (int k = MAX_LOG_V-1; k >= 0; k--){
     77         if (pa[k][u] != pa[k][v]){
     78             u = pa[k][u];
     79             v = pa[k][v];
     80         }
     81     }
     82     return pa[0][u];
     83 }
     84 int seg[MAXN << 2];
     85 void push_up(int pos){
     86     seg[pos] = LCA(seg[pos<<1], seg[pos<<1|1]);
     87 }
     88 void build (int l, int r, int pos){
     89     if (l == r){
     90         seg[pos] = l;
     91         return ;
     92     }
     93     int mid = (l + r) >> 1;
     94     build(l, mid, pos<<1);
     95     build(mid+1, r, pos<<1|1);
     96     push_up(pos);
     97 }
     98 int query (int l, int r, int pos, int ua, int ub){
     99     if (ua <= l && ub >= r){
    100         return seg[pos];
    101     }
    102     int mid = (l + r) >> 1;
    103     int t1 = -1, t2 = -1;
    104     if (ua <= mid){
    105         t1 = query(l, mid, pos<<1, ua, ub);
    106     }
    107     if (ub > mid){
    108         t2 = query(mid+1, r, pos<<1|1, ua, ub);
    109     }
    110     if (t1 == -1 || t2 == -1){
    111         return max(t1, t2);
    112     }else{
    113         return LCA(t1, t2);
    114     }
    115 }
    116 int main()
    117 {
    118     #ifndef ONLINE_JUDGE
    119         freopen("in.txt","r",stdin);
    120     #endif
    121     while (~ scanf ("%d", &n)){
    122         init();
    123         for (int i = 0; i < n-1; i++){
    124             int u, v;
    125             scanf ("%d%d", &u, &v);
    126             Add_Edge(u, v);
    127             Add_Edge(v, u);
    128         }
    129         pre_solve();
    130         build(1, n, 1);
    131         scanf ("%d", &q);
    132         for (int i = 0; i < q; i++){
    133             int ua, ub;
    134             scanf ("%d%d", &ua, &ub);
    135             printf("%d
    ", query(1, n, 1, ua, ub));
    136         }
    137     }
    138     return 0;
    139 }
  • 相关阅读:
    jquery easy ui 学习 (8)basic treegrid
    jquery easy ui 学习 (7) TreeGrid Actions
    jquery easy ui 学习 (6) basic validatebox
    jquery easy ui 学习 (5) windowlayout
    jquery easy ui 学习 (4) window 打开之后 限制操纵后面元素属性
    提示“应用程序无法启动,因为应用程序的并行配置不正确”不能加载 System.Data.SQLite.dll
    visual studio 添加虚线的快捷键
    VS2010打开项目时,出现“已经在解决方案中打开了具有该名称的项目”问题的解决方案
    visual studio 编译时 出现 Files 的值 乱码
    微信 连接被意外关闭
  • 原文地址:https://www.cnblogs.com/oneshot/p/4561916.html
Copyright © 2011-2022 走看看