Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * File: main.cpp
- * Author: Hrayr [HarHro94]
- * Problem:
- * IDE: Visual C++ 2012
- */
- #pragma comment(linker, "/STACK:66777216")
- #define _CRT_SECURE_NO_WARNINGS
- #include <functional>
- #include <algorithm>
- #include <iostream>
- #include <sstream>
- #include <fstream>
- #include <cassert>
- #include <iomanip>
- #include <cstring>
- #include <cstdio>
- #include <string>
- #include <vector>
- #include <ctime>
- #include <queue>
- #include <stack>
- #include <cmath>
- #include <set>
- #include <map>
- using namespace std;
- typedef long long LL;
- typedef long double LD;
- #define pb push_back
- #define mp make_pair
- #define all(v) (v).begin(), (v).end()
- #define sz(v) (int)(v).size()
- const int N = 100007;
- const int V = 40 * N;
- struct persistentSegmentTree
- {
- LL sum[V];
- int ptr, cnt[V], left[V], right[V];
- int rootCnt, roots[N];
- int size;
- LL *xx;
- inline int newLeaf(int c, LL s)
- {
- ++ptr;
- sum[ptr] = s;
- cnt[ptr] = c;
- left[ptr] = 0;
- right[ptr] = 0;
- return ptr;
- }
- inline int newNode(int l, int r)
- {
- ++ptr;
- left[ptr] = l;
- right[ptr] = r;
- sum[ptr] = 0LL;
- cnt[ptr] = 0;
- if (l)
- {
- cnt[ptr] += cnt[l];
- sum[ptr] += sum[l];
- }
- if (r)
- {
- cnt[ptr] += cnt[r];
- sum[ptr] += sum[r];
- }
- return ptr;
- }
- void start(int n, LL x[], int szx)
- {
- xx = x;
- size = szx;
- roots[rootCnt++] = build(0, szx - 1);
- }
- inline int countSmaller(int id, int pos)
- {
- return cntQuery(roots[pos + 1], 0, size - 1, 0, id);
- }
- inline LL sumSmaller(int id, int pos)
- {
- return sumQuery(roots[pos + 1], 0, size - 1, 0, id);
- }
- int build(int tl, int tr)
- {
- if (tl == tr)
- {
- return newLeaf(0, 0LL);
- }
- int tm = (tl + tr) / 2;
- return newNode(build(tl, tm), build(tm + 1, tr));
- }
- LL sumQuery(int T, int tl, int tr, int l, int r)
- {
- if (tl == l && tr == r)
- {
- return sum[T];
- }
- int tm = (tl + tr) >> 1;
- if (r <= tm)
- {
- return sumQuery(left[T], tl, tm, l, r);
- }
- if (l > tm)
- {
- return sumQuery(right[T], tm + 1, tr, l, r);
- }
- return sumQuery(left[T], tl, tm, l, tm) + sumQuery(right[T], tm + 1, tr, tm + 1, r);
- }
- int cntQuery(int T, int tl, int tr, int l, int r)
- {
- if (tl == l && tr == r)
- {
- return cnt[T];
- }
- int tm = (tl + tr) >> 1;
- if (r <= tm)
- {
- return cntQuery(left[T], tl, tm, l, r);
- }
- if (l > tm)
- {
- return cntQuery(right[T], tm + 1, tr, l, r);
- }
- return cntQuery(left[T], tl, tm, l, tm) + cntQuery(right[T], tm + 1, tr, tm + 1, r);
- }
- int update(int T, int tl, int tr, int pos, int delta)
- {
- if (tl == tr)
- {
- return newLeaf(cnt[T] + delta, sum[T] + delta * xx[pos]);
- }
- int tm = (tl + tr) / 2;
- if (pos <= tm)
- {
- return newNode(update(left[T], tl, tm, pos, delta), right[T]);
- }
- return newNode(left[T], update(right[T], tm + 1, tr, pos, delta));
- }
- } X, Y;
- LL sx[N], sy[N], rx[N], ry[N], sumx[N], sumy[N];
- int n, q, sxsize, sysize, x[N], y[N];
- LL myabs(LL x)
- {
- return x < 0LL ? - x : x;
- }
- int main()
- {
- #ifdef harhro94
- freopen("input.txt", "r", stdin);
- freopen("output.txt", "w", stdout);
- #endif
- scanf("%d%d", &n, &q);
- for (int i = 0; i < n; ++i)
- {
- scanf("%d", x + i);
- }
- for (int i = 0; i < n; ++i)
- {
- scanf("%d", y + i);
- }
- for (int i = 0; i < n; ++i)
- {
- rx[i] = x[i] + y[i];
- ry[i] = x[i] - y[i];
- sx[i] = rx[i];
- sy[i] = ry[i];
- }
- sort(sx, sx + n);
- sort(sy, sy + n);
- sxsize = unique(sx, sx + n) - sx;
- sysize = unique(sy, sy + n) - sy;
- for (int i = 1; i <= n; ++i)
- {
- sumx[i] = sumx[i - 1] + rx[i - 1];
- sumy[i] = sumy[i - 1] + ry[i - 1];
- }
- X.start(n, sx, sxsize);
- Y.start(n, sy, sysize);
- cerr << fixed << setprecision(3) << "\nExecution time = " << clock() / 1000.0 << "s\n";
- for (int i = 0; i < n; ++i)
- {
- int lo = 0;
- int hi = sxsize - 1;
- while (lo < hi)
- {
- int mi = (lo + hi + 1) >> 1;
- if (sx[mi] > rx[i])
- {
- hi = mi - 1;
- }
- else
- {
- lo = mi;
- }
- }
- X.roots[X.rootCnt++] = X.update(X.roots[X.rootCnt - 1], 0, X.size - 1, lo, 1);
- }
- for (int i = 0; i < n; ++i)
- {
- int lo = 0;
- int hi = sysize - 1;
- while (lo < hi)
- {
- int mi = (lo + hi + 1) >> 1;
- if (sy[mi] > ry[i])
- {
- hi = mi - 1;
- }
- else
- {
- lo = mi;
- }
- }
- Y.roots[Y.rootCnt++] = Y.update(Y.roots[Y.rootCnt - 1], 0, Y.size - 1, lo, 1);
- }
- cerr << fixed << setprecision(3) << "\nExecution time = " << clock() / 1000.0 << "s\n";
- while (q--)
- {
- int l, r;
- scanf("%d%d", &l, &r);
- --l, --r;
- int cnt = r - l + 1;
- int need = cnt / 2 + 1;
- LL ans = 0LL;
- int lo = 0;
- int hi = sxsize - 1;
- while (lo < hi)
- {
- int mi = (lo + hi) >> 1;
- int c1 = X.countSmaller(mi, r);
- int c2 = X.countSmaller(mi, l - 1);
- if (c1 < need || (c1 - c2) < need)
- {
- lo = mi + 1;
- }
- else
- {
- hi = mi;
- }
- }
- LL med = sx[lo];
- LL all = sumx[r + 1] - sumx[l];
- LL less = X.sumSmaller(lo, r) - X.sumSmaller(lo, l - 1);
- int lessCnt = X.countSmaller(lo, r) - X.countSmaller(lo, l - 1);
- ans += all - 2 * less + lessCnt * med - (cnt - lessCnt) * med;
- lo = 0;
- hi = sysize - 1;
- while (lo < hi)
- {
- int mi = (lo + hi) >> 1;
- int c1 = Y.countSmaller(mi, r);
- int c2 = Y.countSmaller(mi, l - 1);
- if (c1 < need || (c1 - c2) < need)
- {
- lo = mi + 1;
- }
- else
- {
- hi = mi;
- }
- }
- med = sy[lo];
- all = sumy[r + 1] - sumy[l];
- less = Y.sumSmaller(lo, r) - Y.sumSmaller(lo, l - 1);
- lessCnt = Y.countSmaller(lo, r) - Y.countSmaller(lo, l - 1);
- ans += all - 2 * less + lessCnt * med - (cnt - lessCnt) * med;
- if (ans & 1LL)
- {
- printf("%lld.5\n", ans / 2);
- }
- else
- {
- printf("%lld\n", ans / 2);
- }
- }
- #ifdef harhro94
- cerr << fixed << setprecision(3) << "\nExecution time = " << clock() / 1000.0 << "s\n";
- #endif
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement