要求每一对(i,j)的最小距离的和
可以通过题目给出的那些数据列出一个线性方程
x=vit+x0;
x2=vit+x0;
这就是每一个点的运动轨迹
求2个点距离的最小值
当他们的轨迹 在 t<0 的 那边时候2个点的距离的最小值就是他们初始的距离相减的绝对值
而当t>0时,2个点距离的最小值就是0
t要大于0
我们可以列出一个方程组
v1t+x1=v2t+x2
解得:t=(x2-x1)/(v1-v2);
所以 当t<0时
x1<x2&&v1<v2;
我们可以对初始位置sort一遍,然后找他前面速度比他小的点,把他们初始位置的差值加起来就好了
#include<bits/stdc++.h>
using namespace std;
const int maxn=2e5+5;
typedef long long ll;
struct node{
ll x;
ll v;
}a[maxn];
ll b[maxn];
ll s1[maxn];
ll s2[maxn];
ll ask(ll s[],ll pos)
{
ll res=0LL;
while(pos>0){
res+=s[pos];
pos-=(pos&-pos);
}
return res;
}
void update(ll pos,ll x)
{
while(pos<=maxn-5){
s1[pos]++;
s2[pos]+=x;
pos+=(pos&-pos);
}
}
bool cmp(node a,node b)
{
return a.x<b.x;
}
int main()
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%lld",&a[i].x);
}
for(int i=1;i<=n;i++){
scanf("%lld",&a[i].v);
b[i]=a[i].v;
}
sort(a+1,a+1+n,cmp);
sort(b+1,b+1+n);
int m=unique(b+1,b+1+n)-(b+1);
ll res=0LL;
for(int i=1;i<=n;i++){
ll pos=lower_bound(b+1,b+1+n,a[i].v)-b;
ll sum_x=ask(s1,pos);
ll sum=ask(s2,pos);
res+=(sum_x*a[i].x)-(sum);
update(pos,a[i].x);
}
cout<<res<<endl;
return 0;
}