/* Solution for Season 6 Round 6 Problem 5 Senior Author: Anton Chernev */ #include #include using namespace std; #define CONSTANT false #define PROGRESSION true const long long MAX_N = 100000; const long long MAX_SEGMENT_END = 100000; struct Segment { long long x, y; long long index; long long answer; }; struct ArithmeticUpdate { long long a; long long d; ArithmeticUpdate(const long long &_a, const long long &_d) { a = _a; d = _d; } ArithmeticUpdate() {} }; long long N, M; Segment type1[MAX_N], type2[MAX_N]; long long it[3 * MAX_SEGMENT_END]; // it for interval tree stores updated values long long updC[3 * MAX_SEGMENT_END]; // updC for update constant ArithmeticUpdate updAP[3 * MAX_SEGMENT_END]; // updAP for update arithmetic progression bool def; void read() { scanf("%lld%lld", &N, &M); for(long long i = 1; i <= N; i++) scanf("%lld%lld", &type1[i].x, &type1[i].y); for(long long i = 1; i <= M; i++) { scanf("%lld%lld", &type2[i].x, &type2[i].y); type2[i].index = i; } } bool cmp1(Segment el1, Segment el2) { return el1.x < el2.x; } bool cmp2(Segment el1, Segment el2) { return el1.y < el2.y; } bool cmp3(Segment el1, Segment el2) { return el1.index < el2.index; } inline long long APSum(const long long &a, const long long &d, const long long &n) { return a ? n * (2 * a + (n - 1) * d) / 2 : 0LL; } void triggerUpd(long long k, long long l, long long r) { long long len1 = (l + r) / 2 - l + 1, len2 = r - (l + r) / 2; it[k * 2] += len1 * updC[k]; it[k * 2 + 1] += len2 * updC[k]; updC[k * 2] += updC[k]; updC[k * 2 + 1] += updC[k]; updC[k] = 0; if(updAP[k].a) { it[k * 2] += APSum(updAP[k].a, updAP[k].d, len1); it[k * 2 + 1] += APSum(updAP[k].a + len1 * updAP[k].d, updAP[k].d, len2); updAP[k * 2].a += updAP[k].a; updAP[k * 2].d += updAP[k].d; updAP[k * 2 + 1].a += updAP[k].a + len1 * updAP[k].d; updAP[k * 2 + 1].d += updAP[k].d; updAP[k] = ArithmeticUpdate(0, 0); } } void update(long long k, long long l, long long r, long long l1, long long r1, long long val) { if(l1 > r || l > r1) return; if(l1 <= l && r <= r1) { if(def == CONSTANT) // constant update { it[k] += val * (r - l + 1); updC[k] += val; } else { it[k] += APSum(val - (l - l1), -1LL, r - l + 1); updAP[k].a += (val - (l - l1)); updAP[k].d -= 1LL; } return; } triggerUpd(k, l, r); update(k * 2, l, (l + r) / 2, l1, r1, val); update(k * 2 + 1, (l + r) / 2 + 1, r, l1, r1, val); it[k] = it[k * 2] + it[k * 2 + 1]; } long long findInterval(long long k, long long l, long long r, long long l1, long long r1) { if(l1 > r || l > r1) return 0; if(l1 <= l && r <= r1) return it[k]; triggerUpd(k, l, r); return findInterval(k * 2, l, (l + r) / 2, l1, r1) + findInterval(k * 2 + 1, (l + r) / 2 + 1, r, l1, r1); } void addSegment(long long idx) { def = CONSTANT; if(type1[idx].x > 1) update(1, 1, MAX_SEGMENT_END, 1, type1[idx].x - 1, type1[idx].y - type1[idx].x + 1); def = PROGRESSION; update(1, 1, MAX_SEGMENT_END, type1[idx].x, type1[idx].y, type1[idx].y - type1[idx].x + 1); } void solve() { sort(type1 + 1, type1 + N + 1, cmp1); sort(type2 + 1, type2 + M + 1, cmp2); long long j = 1; for(long long i = 1; i <= M; i++) { while(j <= N && type1[j].x <= type2[i].y) { addSegment(j); j++; } type2[i].answer = findInterval(1, 1, MAX_SEGMENT_END, type2[i].x, type2[i].y); } } void print() { sort(type2 + 1, type2 + M + 1, cmp3); for(long long i = 1; i <= M; i++) printf("%lld\n", type2[i].answer); } int main() { freopen("segments.in", "r", stdin); freopen("segments.out", "w", stdout); read(); solve(); print(); } /* 4 3 3 7 2 4 5 6 10 10 6 7 2 4 5 10 //*/