Description:
There are n n n points on a coordinate axis OX. The i − t h i-th i−th point is located at the integer point x i xi xi and has a speed v i vi 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 − t h i-th i−th point at the moment t t t (t can be non-integer) is calculated as x i + t ⋅ v i xi+t⋅vi xi+t⋅vi.
Consider two points i i i and j j j. Let d ( i , j ) d(i,j) 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 ) d(i,j) d(i,j) will be 0.
Your task is to calculate the value ∑ 1 ≤ i < j ≤ n d ( i , j ) \sum_{1≤i<j≤n}d(i,j) ∑1≤i<j≤nd(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 ⋅ 1 0 5 ) n (2≤n≤2⋅10^5) n(2≤n≤2⋅105) — the number of points.
The second line of the input contains n n n integers x 1 , x 2 , … , x n ( 1 ≤ x i ≤ 1 0 8 ) x_1,x_2,…,x_n (1≤x_i≤10^8) 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 n n integers v 1 , v 2 , … , v n ( − 1 0 8 ≤ v i ≤ 1 0 8 ) v_1,v_2,…,v_n (−10^8≤vi≤10^8) v1,v2,…,vn(−108≤vi≤108), where v i v_i vi is the speed of the i − t h i-th i−th point.
Output
Print one integer — the value ∑ 1 ≤ i < j ≤ n d ( i , j ) \sum_{1≤i<j≤n}d(i,j) ∑1≤i<j≤nd(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
解题思路:
给出 n n n 个点和他们的初始位置 x x x 和移动速度 v v v ,问所有点对在任意时刻全部最小值的和是多少,不是同一时刻而是每个点对的最小值的和,可以是很多时刻。
时间可以是任意实数,对于任意两点,如果 x i < = x j x_i<=x_j xi<=xj ,且 x i < = v j x_i<=v_j xi<=vj ,那么 i , j i,j i,j 永远不可能相遇。否则肯定可以相遇,所以只需要计算 x i < = x j x_i<=x_j xi<=xj ,且 x i < = v j x_i<=v_j xi<=vj 的情况即可。这种情况贡献就是距离,树状数组维护一个和就好了。
AC代码:
const int N = 2e5 + 10;
ll c[N][2], b[N], ans, len; //二维数组0维护有几个比他小的,1计算前缀和
int n;
struct node
{
int x;
int v;
} a[N];
bool cmp(node a, node b)
{
return a.x < b.x;
}
void add(int x, int val)
{
while (x <= n)
c[x][0]++, c[x][1] += val, x += lowbit(x);
}
ll ask(int x, int k)
{
ll res = 0;
while (x)
res += c[x][k], x -= lowbit(x);
return res;
}
int main()
{
sd(n);
ans = 0, len = 0;
rep(i, 1, n)
sd(a[i].x);
rep(i, 1, n)
{
sd(a[i].v);
b[i] = a[i].v;
}
sort(a + 1, a + 1 + n, cmp);
sort(b + 1, b + 1 + n);
len = unique(b + 1, b + 1 + n) - b - 1; //不重复元素个数
rep(i, 1, n)
{
int now = lower_bound(b + 1, b + 1 + len, a[i].v) - b; //找到位置比a[i]远并且速度还比a[i]大的,计算贡献
ans += a[i].x * ask(now, 0) - ask(now, 1);
//ask(now, 0)询问得到的是位置比x小速度还小的有几个,
//ask(now, 1)询问得到的是位置比x小速度还小的前缀和,
add(now, a[i].x);
}
pld(ans);
return 0;
}