假设最后答案为
x0,y0
。
然后
ans=∑ni=1max{∣xi−x0∣+∣yi−y0∣}
然后我们令
Xi=xi+yi2,Yi=xi−yi2
,那么答案可以转化为
ans=∑ni=1|Xi−X0|+|Yi−Y0|
。
然后
x,y
两维分别求中位数,用主席树维护。
sb错误坑成狗啊。。。
主席树写错了。。。调了半下午
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int N=100005;
const int M=1800005;
int n,q,a[N],b[N];
inline int read()
{
int a=0,f=1; char c=getchar();
while (c<'0'||c>'9') {if (c=='-') f=-1; c=getchar();}
while (c>='0'&&c<='9') {a=a*10+c-'0'; c=getchar();}
return a*f;
}
struct chairmantree
{
int cnt,tot;
int a[N],num[N],hash[N],root[N];
int ls[M],rs[M],size[M];
long long sum[M];
inline int find(int x)
{
int l=1,r=tot;
while (l<=r)
{
int mid=l+r>>1;
if (hash[mid]==x) return mid;
else if (hash[mid]<x) l=mid+1;
else r=mid-1;
}
}
/*
inline int find(int x)
{
int l=1,r=n,ans;
while (l<=r)
{
int mid=l+r>>1;
if (num[mid]<=x)
ans=mid,l=mid+1;
else r=mid-1;
}
return ans;
}
*/
inline void update(int l,int r,int x,int &y,int val)
{
// cout << val << endl;
y=++cnt;
ls[y]=ls[x]; rs[y]=rs[x]; size[y]=size[x]+1; sum[y]=sum[x]+hash[val];
if (l==r) return;
int mid=l+r>>1;
if (val<=mid) update(l,mid,ls[x],ls[y],val);
else update(mid+1,r,rs[x],rs[y],val);
}
inline void init()
{
for (int i=1;i<=n;i++) num[i]=a[i];
sort(num+1,num+n+1);
hash[++tot]=num[1];
for (int i=2;i<=n;i++)
if (num[i-1]!=num[i]) hash[++tot]=num[i];
for (int i=1;i<=n;i++)
update(1,tot,root[i-1],root[i],find(a[i]));
// cout << endl;
}
inline long long query(int x,int y,int k)
{
// cout << x << " " << y << endl;
int l=1,r=tot,cc=0;
long long ans=0;
while (l!=r)
{
int mid=l+r>>1;
int ret=size[ls[y]]-size[ls[x]];
// cout<< ret << endl;
if (k<=ret)
cc+=size[rs[y]]-size[rs[x]],ans+=sum[rs[y]]-sum[rs[x]],x=ls[x],y=ls[y],r=mid;
else
k-=ret,cc-=ret,ans-=sum[ls[y]]-sum[ls[x]],x=rs[x],y=rs[y],l=mid+1;
}
// cout << "!!! : " << ans << endl;
ans-=sum[y]/size[y]*cc;
return ans;
}
}X,Y;
int main()
{
n=read(); q=read();
for (int i=1;i<=n;i++) a[i]=read();
for (int i=1;i<=n;i++) b[i]=read();
for (int i=1;i<=n;i++)
X.a[i]=a[i]+b[i],Y.a[i]=a[i]-b[i];
X.init(); Y.init();
// for (int i=1;i<=n;i++)
// cout << Y.size[Y.root[i]] << " ";
// for (int i=1;i<=X.cnt;i++)
// cout << X.sum[i] << " " ; cout << endl;
while (q--)
{
int l=read(),r=read();
int mid=(r-l)/2+1;
// cout << X.query(X.root[l-1],X.root[r],mid) << endl;
printf("%.2lf\n",(double)(X.query(X.root[l-1],X.root[r],mid)+Y.query(Y.root[l-1],Y.root[r],mid))/2.0);
}
return 0;
}