双面间谍(spy)

时间:2021-06-16 13:55:44

双面间谍

链接

分析:

  戳这

代码:

#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=,f=;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-;
for(;isdigit(ch);ch=getchar())x=x*+ch-'';return x*f;
} const int N = ;
int a[N], b[N], x[N], y[N], dx[N], dy[N]; struct SegmentTree{
int Root[N], ls[N * ], rs[N * ], cnt[N * ], Index, n, Now, disc[N];
LL sum[N * ], Ans;
SegmentTree() { n = ; }
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] + ;
if (l == r) return ;
int mid = (l + r) >> ;
if (p <= mid) rs[now] = rs[pre], Insert(l, mid, ls[now], ls[pre], p);
else ls[now] = ls[pre], Insert(mid + , 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) >> , 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 + , 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 = ;
T1.Ans = , T1.Now = ;
T1.query(, T1.n, T1.Root[r], T1.Root[l - ], (r - l + + ) / );
ans += T1.Ans; T2.Ans = , T2.Now = ;
T2.query(, T2.n, T2.Root[r], T2.Root[l - ], (r - l + + ) / );
ans += T2.Ans; printf("%.2lf\n", ans / 2.0);
} signed main() {
int n = read(), m = read(), cx = , cy = ;
for (int i = ; i <= n; ++i) a[i] = read();
for (int i = ; 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 + , T1.disc + n + );
sort(T2.disc + , T2.disc + n + );
for (int i = ; 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 = ; i <= n; ++i) {
x[i] = lower_bound(T1.disc + , T1.disc + cx + , x[i]) - T1.disc;
y[i] = lower_bound(T2.disc + , T2.disc + cy + , y[i]) - T2.disc;
}
for (int i = ; i <= n; ++i) T1.n = max(T1.n, x[i]), T2.n = max(T2.n, y[i]);
for (int i = ; i <= n; ++i) {
T1.Insert(, T1.n, T1.Root[i], T1.Root[i - ], x[i]);
T2.Insert(, T2.n, T2.Root[i], T2.Root[i - ], y[i]);
}
while (m --) solve();
return ;
}