主席树代码实现
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