#include<iostream> #include<cstdio> #include<sstream> #include<string> #include<vector> #include<list> #include<set> #include<map> #include<stack> #include<queue> #include<algorithm> #include<cmath> #pragma warning(disable:4996) using std::cin; using std::cout; using std::endl; using std::stringstream; using std::string; using std::vector; using std::list; using std::pair; using std::set; using std::multiset; using std::map; using std::multimap; using std::stack; using std::queue; using std::equal_range; template<typename ElemType> class Interval { public: ElemType left, right; vector<ElemType>height; Interval() { left = right = 0; } Interval(const ElemType &l, const ElemType &r) { left = l; right = r; } ElemType mid() { return left + (length() - 1) / 2; } ElemType length() { return right - left + 1; } }; template<typename ElemType> class SegTree { private: vector<Interval<ElemType> >tree; public: SegTree() {} SegTree(const ElemType &n) { tree.resize(4 * n); } void resize(const ElemType &n) { tree.resize(n); } void update_parent(const ElemType &parent) { tree[parent].height.assign(tree[parent * 2].height.begin(), tree[parent * 2].height.end()); tree[parent].height.insert(tree[parent].height.end(), tree[parent * 2 + 1].height.begin(), tree[parent * 2 + 1].height.end()); sort(tree[parent].height.begin(), tree[parent].height.end()); } void build(Interval<ElemType>interval, ElemType parent, ElemType &size) { tree[parent] = interval; if (interval.length() == 1) { int height; scanf("%d", &height); tree[parent].height.push_back(height); size = std::max(size, parent); return;//当为元线段时停止递归 } ElemType mid = (interval.left + interval.right) / 2; build({ interval.left,mid }, 2 * parent, size); build({ mid + 1,interval.right }, 2 * parent + 1, size); update_parent(parent); } int getBrick(Interval<ElemType>interval, ElemType parent, const ElemType &height) { if (tree[parent].left == interval.left&&interval.right == tree[parent].right) { auto iter = equal_range(tree[parent].height.begin(), tree[parent].height.end(), height); return iter.second - tree[parent].height.begin(); } ElemType mid = tree[parent].mid(); if (interval.right <= mid) { return getBrick(interval, parent * 2, height); } else if (interval.left > mid) { return getBrick(interval, parent * 2 + 1, height); } return getBrick({ interval.left,mid }, parent * 2, height) + getBrick({ mid + 1,interval.right }, parent * 2 + 1, height); } }; int main() { //freopen("input.txt", "r", stdin); //freopen("output.txt","w",stdout); int T, count = 0; cin >> T; while (T--) { int n, m; cin >> n >> m; SegTree<int>segtree(n); int size = 0; segtree.build({ 1,n }, 1,size); segtree.resize(size + 1); printf("Case %d:\n", ++count); while (m--) { int left, right, height; scanf("%d%d%d", &left, &right, &height); printf("%d\n", segtree.getBrick({ left + 1,right + 1 }, 1, height)); } } return 0; }