• 主席树代码实现


      1 // Code From ftiasch 
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <climits>
      5 #include <algorithm>
      6 using namespace std;
      7 
      8 const int N = 111111;
      9 const int INF = 1000000000;
     10 
     11 struct Node {
     12     int minimum;
     13     Node *left, *right;
     14 
     15     Node(int m, Node *l, Node *r): minimum(m), left(l), right(r) {
     16     }
     17 };
     18 
     19 int n, m, coordinate[N], from[N], to[N], length[N], order[N];
     20 Node* trees[N];
     21 
     22 #define is_leaf (lower + 1 == upper)
     23 #define mider ((lower + upper) >> 1)
     24 
     25 Node* build(int lower, int upper) {
     26     if (lower >= upper) {
     27         return NULL;
     28     }
     29     return new Node(INF,
     30             is_leaf? NULL: build(lower, mider),
     31             is_leaf? NULL: build(mider, upper));
     32 }
     33 
     34 Node* insert(Node *root, int lower, int upper, int key, int value) {
     35     if (key < lower || upper <= key) {
     36         return root;
     37     }
     38     return new Node(min(root->minimum, value),
     39             is_leaf? NULL: insert(root->left, lower, mider, key, value),
     40             is_leaf? NULL: insert(root->right, mider, upper, key, value));
     41 }
     42 
     43 int query(Node *root, int lower, int upper, int key) {
     44     if (upper <= key) {
     45         return INF;
     46     }
     47     if (key <= lower) {
     48         return root->minimum;
     49     }
     50     return min(query(root->left, lower, mider, key),
     51             query(root->right, mider, upper, key));
     52 }
     53 
     54 #undef mider
     55 #undef is_leaf
     56 
     57 bool compare(int i, int j) {
     58     return to[i] < to[j];
     59 }
     60 
     61 int main() {
     62     scanf("%d%d", &n, &m);
     63     coordinate[0] = 0;
     64     for (int i = 0; i < n - 1; ++ i) {
     65         int length;
     66         scanf("%d", &length);
     67         coordinate[i + 1] = coordinate[i] + length;
     68     }
     69     for (int i = 0; i < m; ++ i) {
     70         scanf("%d%d%d", from + i, to + i, length + i);
     71         from[i] --;
     72         to[i] --;
     73     }
     74     for (int i = 0; i < m; ++ i) {
     75         order[i] = i;
     76     }
     77     // u <= from[i] to[i] <= v
     78     // form[i] - u + v - to[i]
     79     sort(order, order + m, compare);
     80     Node *tree = build(0, n);
     81     for (int iter = 0; iter < m; ++ iter) {
     82         int i = order[iter];
     83         tree = insert(tree, 0, n, from[i],
     84                 coordinate[from[i]] - coordinate[to[i]] + length[i]);
     85         trees[iter] = tree;
     86     }
     87     int q;
     88     scanf("%d", &q);
     89     while (q > 0) {
     90         q --;
     91         int u, v;
     92         scanf("%d%d", &u, &v);
     93         u --;
     94         v --;
     95         int result = u <= v? coordinate[v] - coordinate[u]: INF;
     96         int lower = 0;
     97         int upper = m - 1;
     98         while (lower < upper) {
     99             int mider = (lower + upper + 1) >> 1;
    100             if (to[order[mider]] <= v) {
    101                 lower = mider;
    102             } else {
    103                 upper = mider - 1;
    104             }
    105         }
    106         if (lower <= upper) {
    107             Node *root = trees[lower];
    108             result = min(result,
    109                     query(root, 0, n, u) - coordinate[u] + coordinate[v]);
    110         }
    111         printf("%d\n", result);
    112     }
    113     return 0;
    114 }
    115 
    116 // 1 ~ N
  • 相关阅读:
    【JZOJ3188】找数【数论,数学】
    【JZOJ3187】的士【模拟】
    【JZOJ3187】的士【模拟】
    【洛谷P1641】生成字符串【数论,数学】
    【洛谷P1896】互不侵犯【状压dp】
    聚集索引与非聚集索引
    哈希索引
    索引能提高检索速度,降低维护速度
    MySQL索引基本知识
    注解
  • 原文地址:https://www.cnblogs.com/yefeng1627/p/3109336.html
Copyright © 2020-2023  润新知