EntropyIncreaser

RMQ_CartesianTree

Apr 25th, 2018
172
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 1.69 KB | None | 0 0
  1. #include <cstdio>
  2.  
  3. #include <algorithm>
  4. #include <vector>
  5.  
  6. using namespace std;
  7.  
  8. typedef long long ll;
  9.  
  10. struct Edge {
  11.     int v;
  12.     Edge* next;
  13. };
  14.  
  15. const int N = 100010, M = 1000010;
  16.  
  17. int n, m;
  18. int a[N], stk[N], f[N], rk[N], ver[N];
  19. int lca[M];
  20. bool vis[N];
  21. vector<pair<int, int> > qry[N];
  22. Edge* g[N];
  23.  
  24. void addEdge(int u, int v);
  25. int find(int x);
  26. void merge(int x, int y);
  27. void dfs(int u);
  28.  
  29. int main() {
  30.     scanf("%d%d", &n, &m);
  31.     for (int i = 1; i <= n; ++i)
  32.         scanf("%d", &a[i]);
  33.     int r = 1;
  34.     stk[1] = 1;
  35.     for (int i = 2; i <= n; ++i) {
  36.         int lst = 0;
  37.         while (r > 0 && a[i] > a[stk[r]]) {
  38.             if (lst)
  39.                 addEdge(stk[r], lst);
  40.             lst = stk[r];
  41.             --r;
  42.         }
  43.         if (lst)
  44.             addEdge(i, lst);
  45.         stk[++r] = i;
  46.     }
  47.     while (r > 1) {
  48.         addEdge(stk[r - 1], stk[r]);
  49.         --r;
  50.     }
  51.     for (int i = 1; i <= m; ++i) {
  52.         int u, v;
  53.         scanf("%d%d", &u, &v);
  54.         qry[u].push_back(make_pair(v, i));
  55.         qry[v].push_back(make_pair(u, i));
  56.     }
  57.     dfs(stk[1]);
  58.     for (int i = 1; i <= m; ++i)
  59.         printf("%d\n", a[lca[i]]);
  60.     return 0;
  61. }
  62.  
  63. void addEdge(int u, int v) {
  64.     static Edge pool[N];
  65.     static Edge* p = pool;
  66.     ++p;
  67.     p->v = v;
  68.     p->next = g[u];
  69.     g[u] = p;
  70. }
  71.  
  72. int find(int x) {
  73.     return f[x] == x ? x : f[x] = find(f[x]);
  74. }
  75.  
  76. void merge(int x, int y) {
  77.     x = find(x);
  78.     y = find(y);
  79.     if (rk[x] < rk[y]) {
  80.         f[x] = y;
  81.     } else if (rk[x] > rk[y]) {
  82.         f[y] = x;
  83.     } else {
  84.         f[x] = y;
  85.         ++rk[y];
  86.     }
  87. }
  88.  
  89. void dfs(int u) {
  90.     vis[u] = true;
  91.     f[u] = u;
  92.     ver[u] = u;
  93.     for (Edge* p = g[u]; p; p = p->next) {
  94.         dfs(p->v);
  95.         merge(u, p->v);
  96.         ver[find(u)] = u;
  97.     }
  98.     for (int i = 0; i < qry[u].size(); ++i)
  99.         if (vis[qry[u][i].first])
  100.             lca[qry[u][i].second] = ver[find(qry[u][i].first)];
  101. }
Advertisement
Add Comment
Please, Sign In to add comment