Moving Points(树状数组)

There are n points on a coordinate axis OX. The i-th point is located at the integer point xi and has a speed vi. It is guaranteed that no two points occupy the same coordinate. All n points move with the constant speed, the coordinate of the i-th point at the moment t (t can be non-integer) is calculated as xi+t⋅vi.

Consider two points i and j. Let d(i,j) be the minimum possible distance between these two points over any possible moments of time (even non-integer). It means that if two points i and j coincide at some moment, the value d(i,j) will be 0.

Your task is to calculate the value ∑1≤i<j≤n d(i,j) (the sum of minimum distances over all pairs of points).

Input
The first line of the input contains one integer n (2≤n≤2⋅105) — the number of points.

The second line of the input contains n integers x1,x2,…,xn (1≤xi≤108), where xi is the initial coordinate of the i-th point. It is guaranteed that all xi are distinct.

The third line of the input contains n integers v1,v2,…,vn (−108≤vi≤108), where vi is the speed of the i-th point.

Output
Print one integer — the value ∑1≤i<j≤n d(i,j) (the sum of minimum distances over all pairs of points).

Examples
input
3
1 3 2
-100 2 3
output
3
input
5
2 1 4 3 5
2 2 2 3 4
output
19
input
2
2 1
-3 0
output
0

思路
对于一组点i,j,且xi<xj,存在多种情况
1.vi<=vj 这种情况下,i,j两者的相对距离会随时间逐渐增大,那么两者间的最小距离即为初始间距(xj-xi)
2.vi>vj 这种情况下,,i,j两者的相对距离会随时间逐渐减小,那么在数轴上存在一点使得两点距离为0
因此可以用树状数组来解决该题,根据每个点的初始位置进行排序,并对每个点的速度进行离散化,那么答案即为每个点与该点出现前的所有速度小于该点的初始间距之和,可以通过树状数组维护。

代码实现

#pragma GCC optimize(3,"Ofast","inline")
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int N=2e5+5;
const int M=1e6+5;
const int INF=0x3f3f3f3f;
const ll LINF=1e16;
const ull sed=31;
const ll mod=1e9+7;
const double PI=acos(-1.0);
const double eps=1e-9;
typedef pair<ll,ll>P;
typedef pair<double,double>Pd;

struct node
{
    ll x,v;
}p[N];

int n;
ll s1[N],s2[N],v[N];;
inline int lowbit(int x) {return x&(-x);}
void add(int x,ll k,ll s[])
{
    for(int i=x;i<=n;i+=lowbit(i)) s[i]+=k;
}
ll sum(int x,ll s[])
{
    ll ans=0;
    for(int i=x;i;i-=lowbit(i)) ans+=s[i];
    return ans;
}
bool cmp(node a,node b)
{
    return (a.x<b.x || (a.x==b.x && a.v<b.v));
}

int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++) scanf("%lld",&p[i].x);
    for(int i=1;i<=n;i++)
    {
        scanf("%lld",&p[i].v);
        v[i]=p[i].v;
    }
    sort(v+1,v+1+n);
    sort(p+1,p+1+n,cmp);
    ll ans=0;
    for(int i=1;i<=n;i++)
    {
        int pt=lower_bound(v+1,v+1+n,p[i].v)-v;
        ans+=sum(pt,s1)*p[i].x-sum(pt,s2);
        add(pt,1,s1);
        add(pt,p[i].x,s2);
    }
    printf("%lld\n",ans);
    return 0;
}

发布了235 篇原创文章 · 获赞 13 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/weixin_43935894/article/details/104496708