usaco

Clean implementations of solutions to USACO problems

  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
#include <bits/stdc++.h>
#define f first
#define s second
using namespace std;
using ll = long long;
using ii = pair<int, int>;
constexpr int MX = 2e5+5, B = 300;

int C[MX], L[MX], R[MX], ST[20][MX], ans[MX];
pair<ii, int> P[MX];

inline int query(int i, int j) {
	if (i > j) return MX;
	int k = 31-__builtin_clz(j-i+1);
	return min(ST[k][i], ST[k][j-(1<<k)+1]);
}

int main() {
	if (fopen("in", "r")) freopen("in", "r", stdin), freopen("out", "w", stdout);
	cin.tie(0)->sync_with_stdio(0);
	
	int N, Q; cin >> N >> Q;
	for (int i = 0; i < N; ++i) cin >> C[i];
	for (int i = 0; i < Q; ++i) {
		cin >> P[i].f.f >> P[i].f.s;
		--P[i].f.f, --P[i].f.s, P[i].s = i;
	}

	vector<int> tmp(N+1, -1);
	for (int i = 0; i < N; ++i) L[i] = tmp[C[i]], tmp[C[i]] = i;
	fill(begin(tmp), end(tmp), -1);
	for (int i = N-1; i >= 0; --i) R[i] = tmp[C[i]], tmp[C[i]] = i;
	
	memset(ST, '?', sizeof ST);
	for (int i = 0; i < N; ++i) ST[0][i] = C[i];
	for (int i = 0; i < 18; ++i)
		for (int j = 0; j+(1<<(i+1)) < N; ++j) ST[i+1][j] = min(ST[i][j], ST[i][j+(1<<i)]);

	sort(P, P+Q, [](auto a, auto b) {
		return a.f.f/B == b.f.f/B ? ((a.f.f/B)%2 ? a.f.s > b.f.s : a.f.s < b.f.s) : a.f.f/B < b.f.f/B;
	});
	
	int l = 0, r = -1, cur = 0;
	for (int i = 0; i < Q; ++i) {
		while (l > P[i].f.f) {
			--l;
			if (R[l] == -1 || R[l] > r || query(l+1, R[l]-1) < C[l]) ++cur;
		}
		while (r < P[i].f.s) {
			++r;
			if (L[r] == -1 || L[r] < l || query(L[r]+1, r-1) < C[r]) ++cur;
		}
		while (l < P[i].f.f) {
			if (R[l] == -1 || R[l] > r || query(l+1, R[l]-1) < C[l]) --cur;
			++l;
		}
		while (r > P[i].f.s) {
			if (L[r] == -1 || L[r] < l || query(L[r]+1, r-1) < C[r]) --cur;
			--r;
		}
		ans[P[i].s] = cur;
	}
	for (int i = 0; i < Q; ++i) cout << ans[i] << '\n';
}