#include #include #include using namespace std; vector > samples; int INF = 1000000000; struct InTree; vector tree; struct InTree { vector::iterator left; vector::iterator right; int start, stop; int startval, stopval; int mini, maxi, count, sum; void initialize(int start, int stop) { //cerr << start << " " << stop << " b " << endl; this->start = start; this->stop = stop; startval = samples[start].first; stopval = samples[stop].first; if(stop - start <= 1) { count = 0; sum = 0; maxi = 0; mini = 0; if(stop - start == 1) { count = 1; sum = samples[start].second; maxi = sum; mini = sum; } //cerr << start << " " << stop << " " << count << endl; return; } //cerr << startval << " " << stopval << " s" << endl; tree.push_back(InTree()); left = tree.end(); left--; //cerr << "X" << endl; //cerr << tree.size() << endl; tree.push_back(InTree()); //cerr << "Y" << endl; right = tree.end(); right--; left->initialize(start, (start + stop) / 2); right->initialize((start + stop) / 2, stop); count = left->count + right->count; sum = left->sum + right->sum; maxi = max(left->maxi, right->maxi); mini = min(left->mini, right->mini); //cerr << start << " " << stop << " " << count << " " << left->count << " " << right->count << endl; } void debug(int ind = 0) { for(int j = 0; j < ind; j++) cerr << " "; cerr << startval << " " << stopval << ", " << start << " " << stop << ", " << mini << " " << count << endl; if(count > 1) { left->debug(ind+1); right->debug(ind+1); } } int getMaxi(int from, int to) { if(startval >= to || stopval <= from) return 0; if(stop - start == 1) return maxi; if(from <= startval && to >= stopval) return maxi; return max(left->getMaxi(from, to), right->getMaxi(from, to)); } int getMini(int from, int to) { if(startval >= to || stopval <= from) return 2000000000; if(stop - start == 1) return mini; if(from <= startval && to >= stopval) return mini; return min(left->getMini(from, to), right->getMini(from, to)); } int getCount(int from, int to) { if(startval >= to || stopval <= from) return 0; if(stop - start == 1) { if(from > startval) return 0; return count; } if(from <= startval && to >= stopval) return count; return (left->getCount(from, to) + right->getCount(from, to)); } int getSum(int from, int to) { if(startval >= to || stopval <= from) return 0; if(stop - start == 1) return sum; if(from <= startval && to >= stopval) return sum; return (left->getSum(from, to) + right->getSum(from, to)); } }; void doCase(int n) { samples.clear(); tree.clear(); samples.reserve(n); tree.reserve(2*n); for(int i = 0; i < n; i++) { int t, v; cin >> t >> v; samples.push_back(make_pair(t, v)); } samples.push_back(make_pair(2000000000, 0)); tree.push_back(InTree()); tree[0].initialize(0, n); //tree[0].debug(); samples.pop_back(); int queries; cin >> queries; for(int i = 0; i < queries; i++) { string op, fun; int time; cin >> op >> fun >> time; int result = 0; for(int j = 0; j < n; j++) { int stopTime = samples[j].first; int startTime = stopTime - time; int currentVal = samples[j].second; int compareVal; int remainder = 0; int count = tree[0].getCount(startTime, stopTime); //cerr << j << " " << startTime << " " << stopTime << " " << tree[0].getMini(startTime, stopTime) << endl; if(count == 0) continue; if(fun == "max") compareVal = tree[0].getMaxi(startTime, stopTime); else if(fun == "min") compareVal = tree[0].getMini(startTime, stopTime); else if(fun == "avg") { int sum = tree[0].getSum(startTime, stopTime); compareVal = sum / count; remainder = sum - count * compareVal; } if(op == "gt") { if(currentVal > compareVal) { //cerr << "ok " << j << " " << startTime << " " << stopTime << endl; result++; } } else if(op == "lt") { if(currentVal < compareVal) { //cerr << "ok " << j << " " << startTime << " " << stopTime << endl; result++; } else if(currentVal == compareVal && remainder > 0) { //cerr << "ok2 " << j << " " << startTime << " " << stopTime << endl; result++; } } } cout << result << endl; } } int main() { int n; cin >> n; while(!cin.fail()) { doCase(n); cin >> n; } }