library

Some useful algorithms for competitive programming

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20
  21. 21
  22. 22
  23. 23
  24. 24
  25. 25
  26. 26
  27. 27
  28. 28
  29. 29
  30. 30
  31. 31
  32. 32
  33. 33
  34. 34
  35. 35
  36. 36
  37. 37
  38. 38
  39. 39
  40. 40
  41. 41
  42. 42
  43. 43
  44. 44
  45. 45
  46. 46
  47. 47
  48. 48
  49. 49
  50. 50
  51. 51
  52. 52
  53. 53
  54. 54
  55. 55
  56. 56
  57. 57
  58. 58
  59. 59
  60. 60
  61. 61
  62. 62
  63. 63
  64. 64
  65. 65
  66. 66
  67. 67
  68. 68
  69. 69
  70. 70
using namespace std;
constexpr auto MAX_N = 100005;

int A[MAX_N], seg[4 * MAX_N], tmp[4 * MAX_N];

void build(int node, int start, int end) {
	if (start == end) seg[node] = A[start];
	else {
		int mid = (start + end) >> 1;
		build(node << 1, start, mid);
		build((node << 1) + 1, mid + 1, end);
		seg[node] = seg[node << 1] + seg[(node << 1) + 1];
	}
}

void update(int node, int start, int end, int idx, int val) {
	if (start == end) seg[node] += val;
	else {
		int mid = (start + end) >> 1;
		(start <= idx && idx <= mid) ? update((node << 1), start, mid, idx, val) : update((node << 1) + 1, mid + 1, end, idx, val);
		seg[node] = seg[node << 1] + seg[(node << 1) + 1];
	}
}

int query(int node, int start, int end, int left, int right) {
	if (left > end || right < start) return 0;
	if (left <= start && right >= end) return seg[node];
	int mid = (start + end) >> 1;
	return query(node << 1, start, mid, left, right) + query((node << 1) + 1, mid + 1, end, left, right);
}

void update_range(int node, int start, int end, int left, int right, int val) {
	if (tmp[node]) {
		seg[node] += (end - start + 1) * tmp[node];
		if (start != end) {
			tmp[node << 1] += tmp[node];
			tmp[(node << 1) + 1] += tmp[node];
		}
		tmp[node] = 0;
	}
	if (start > end || left > end || right < start) return;
	if (left <= start && right >= end) {
		seg[node] += (end - start + 1) * val;
		if (start != end) {
			tmp[node << 1] += val;
			tmp[(node << 1) + 1] += val;
		}
	}
	else {
		int mid = (start + end) >> 1;
		update_range(node << 1, start, mid, left, right, val);
		update_range((node << 1) + 1, mid + 1, end, left, right, val);
		seg[node] = seg[node << 1] + seg[(node << 1) + 1];
	}
}

int query_range(int node, int start, int end, int left, int right) {
	if (start > end || left > end || right < start) return 0;
	if (tmp[node]) {
		seg[node] += (end - start + 1) * tmp[node];
		if (start != end) {
			tmp[node << 1] += tmp[node];
			tmp[(node << 1) + 1] += tmp[node];
		}
		tmp[node] = 0;
	}
	if (left <= start && right >= end) return seg[node];
	int mid = (start + end) >> 1;
	return query_range(node << 1, start, mid, left, right) + query_range((node << 1) + 1, mid + 1, end, left, right);
}