双面间谍
分析:
代码:
#include<cstdio> #include<algorithm> #include<cstdio> #include<cstring> #include<iostream> #include<cmath> #include<set> #include<queue> #include<vector> #include<map> #include<bitset> using namespace std; typedef long long LL; inline int read() { int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1; for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';return x*f; } const int N = 200005; int a[N], b[N], x[N], y[N], dx[N], dy[N]; struct SegmentTree{ int Root[N], ls[N * 25], rs[N * 25], cnt[N * 25], Index, n, Now, disc[N]; LL sum[N * 25], Ans; SegmentTree() { n = 0; } void Insert(int l,int r,int &now,int pre,int p) { if (!now) now = ++Index; sum[now] = sum[pre] + disc[p]; cnt[now] = cnt[pre] + 1; if (l == r) return ; int mid = (l + r) >> 1; if (p <= mid) rs[now] = rs[pre], Insert(l, mid, ls[now], ls[pre], p); else ls[now] = ls[pre], Insert(mid + 1, r, rs[now], rs[pre], p); } void query(int l,int r,int now,int pre,int k) { if (l == r) { Now = disc[l]; return ; } int mid = (l + r) >> 1, x = cnt[ls[now]] - cnt[ls[pre]]; if (k <= x) { query(l, mid, ls[now], ls[pre], k); Ans += (sum[rs[now]] - sum[rs[pre]]) - 1ll * Now * (cnt[rs[now]] - cnt[rs[pre]]); } else { query(mid + 1, r, rs[now], rs[pre], k - x); Ans += 1ll * Now * x - (sum[ls[now]] - sum[ls[pre]]); } } }T1, T2; void solve() { int l = read(), r = read(); LL ans = 0; T1.Ans = 0, T1.Now = 0; T1.query(0, T1.n, T1.Root[r], T1.Root[l - 1], (r - l + 1 + 1) / 2); ans += T1.Ans; T2.Ans = 0, T2.Now = 0; T2.query(0, T2.n, T2.Root[r], T2.Root[l - 1], (r - l + 1 + 1) / 2); ans += T2.Ans; printf("%.2lf ", ans / 2.0); } signed main() { int n = read(), m = read(), cx = 1, cy = 1; for (int i = 1; i <= n; ++i) a[i] = read(); for (int i = 1; i <= n; ++i) { b[i] = read(); x[i] = a[i] + b[i], y[i] = a[i] - b[i]; T1.disc[i] = x[i], T2.disc[i] = y[i]; } sort(T1.disc + 1, T1.disc + n + 1); sort(T2.disc + 1, T2.disc + n + 1); for (int i = 2; i <= n; ++i) { if (T1.disc[i] != T1.disc[cx]) T1.disc[++cx] = T1.disc[i]; if (T2.disc[i] != T2.disc[cy]) T2.disc[++cy] = T2.disc[i]; } for (int i = 1; i <= n; ++i) { x[i] = lower_bound(T1.disc + 1, T1.disc + cx + 1, x[i]) - T1.disc; y[i] = lower_bound(T2.disc + 1, T2.disc + cy + 1, y[i]) - T2.disc; } for (int i = 1; i <= n; ++i) T1.n = max(T1.n, x[i]), T2.n = max(T2.n, y[i]); for (int i = 1; i <= n; ++i) { T1.Insert(0, T1.n, T1.Root[i], T1.Root[i - 1], x[i]); T2.Insert(0, T2.n, T2.Root[i], T2.Root[i - 1], y[i]); } while (m --) solve(); return 0; }