#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; template<typename ElemType> class Interval { public: ElemType first, second, ceil,floor; Interval() { first = second = ceil =floor= 0; } Interval(const ElemType &f, const ElemType &s) { first = f; second = s; ceil = floor=0; } Interval(const pair<ElemType, ElemType>&p) { first = p.first; second = p.second; ceil = floor=0; } ElemType mid() { return first + (length() - 1) / 2; } ElemType length() { return second - first + 1; } }; template<typename ElemType> class SegTree { private: vector<Interval<ElemType> >tree; public: SegTree() {} SegTree(const ElemType &n) { tree.resize(4 * n); } int size() { return tree.size(); } void resize(const ElemType &n) { tree.resize(n); } void update_parent(const int &parent) { tree[parent].ceil = std::max(tree[parent * 2].ceil, tree[parent * 2 + 1].ceil); tree[parent].floor = std::min(tree[parent * 2].floor, tree[parent * 2 + 1].floor); } //以数组形式建立线段树,当数据离散化之后,调用build(min,max,1) void build(Interval<ElemType>interval, ElemType parent, ElemType &size) { tree[parent] = interval; if (interval.first == interval.second) { scanf("%d", &tree[parent].ceil); tree[parent].floor = tree[parent].ceil; size = std::max(size, parent); return;//当为元线段时停止递归 } ElemType mid = (interval.first + interval.second) / 2; build({ interval.first,mid }, 2 * parent, size); build({ mid + 1,interval.second }, 2 * parent + 1, size); update_parent(parent); } int getBrick(Interval<ElemType>interval, ElemType parent, const ElemType &height) { if (tree[parent].first == interval.first&&interval.second == tree[parent].second) { if (height >= tree[parent].ceil) { return tree[parent].length(); } if (height < tree[parent].floor) { return 0; } if (tree[parent].length() == 1) { return 0; } } ElemType mid = tree[parent].mid(); if (interval.second <= mid) { return getBrick(interval, parent * 2, height); } else if (interval.first > mid) { return getBrick(interval, parent * 2 + 1, height); } else { return getBrick({ interval.first,mid }, parent * 2, height) + getBrick({ mid + 1,interval.second }, 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,size=0; scanf("%d%d", &n, &m); SegTree<int>segtree(n); 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; }