F. Moving Points
Posted lijiahui-123
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了F. Moving Points相关的知识,希望对你有一定的参考价值。
There are nn points on a coordinate axis OXOX . The ii -th point is located at the integer point xixi and has a speed vivi . It is guaranteed that no two points occupy the same coordinate. All nn points move with the constant speed, the coordinate of the ii -th point at the moment tt (tt can be non-integer) is calculated as xi+t⋅vixi+t⋅vi .
Consider two points ii and jj . Let 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 ii and jj coincide at some moment, the value d(i,j)d(i,j) will be 00 .
Your task is to calculate the value ∑1≤i<j≤n∑1≤i<j≤n d(i,j)d(i,j) (the sum of minimum distances over all pairs of points).
The first line of the input contains one integer nn (2≤n≤2⋅1052≤n≤2⋅105 ) — the number of points.
The second line of the input contains nn integers x1,x2,…,xnx1,x2,…,xn (1≤xi≤1081≤xi≤108 ), where xixi is the initial coordinate of the ii -th point. It is guaranteed that all xixi are distinct.
The third line of the input contains nn integers v1,v2,…,vnv1,v2,…,vn (−108≤vi≤108−108≤vi≤108 ), where vivi is the speed of the ii -th point.
Print one integer — the value ∑1≤i<j≤n∑1≤i<j≤n d(i,j)d(i,j) (the sum of minimum distances over all pairs of points).
3 1 3 2 -100 2 3
3
5 2 1 4 3 5 2 2 2 3 4
19
2 2 1 -3 0
0
题解:
Tutorial
1311F - Moving Points
Let‘s understand when two points ii and jj coincide. Let xi<xjxi<xj . Then they are coincide when vi>vjvi>vj . Otherwise, these two points will never coincide and the distance between them will only increase.
So, we need to consider only the initial positions of points. Let‘s sort all points by xixi and consider them one by one from left to right. Let the ii -th point be the rightmost in the pair of points that we want to add to the answer.
We need to find the number of points jj such that xj<xixj<xi and vj≤vivj≤vi and the sum of xjxj for such points as well. We can do this using two BITs (Fenwick trees) if we compress coordinates (all values vv ) and do some kind of "scanline" by values xx . Let the number of such points be cntcnt and the sum of coordinates of such points be sumsum . Then we can increase the answer by xi⋅cnt−sumxi⋅cnt−sum and add our current point to the Fenwick trees (add 11 to the position vivi in the first tree and xixi to the position vivi in the second tree). When we want to find the number of required points and the sum of its coordinates, we just need to find the sum on the prefix two times in Fenwick trees. Note that you can use any "online" logarithmic data structure you like in this solution (such as treap and segment tree).
There is also another solution that uses pbds. Let‘s do the same thing, but there is one problem. Such data structure does not have "sum on prefix" function, so we have to replace it somehow. To do this, let‘s calculate only xi⋅cntxi⋅cnt part when we go from left to right. Then let‘s clear our structure, go among all points again but from right to left and calculate the same thing, but with the opposite sign (find the number of points jj such that xj>xixj>xi and vj≥vivj≥vi ). When we go from right to left, we need to decrease the answer by xi⋅cntxi⋅cnt . It is some kind of "contribution to the sum" technique.
Time complexity: O(nlogn)O(nlog?n) .
Solution (Fenwick tree)
#include <bits/stdc++.h>
using namespace std;
long long get(vector<long long> &f, int pos) {
long long res = 0;
for (; pos >= 0; pos = (pos & (pos + 1)) - 1)
res += f[pos];
return res;
}
void upd(vector<long long> &f, int pos, int val) {
for (; pos < int(f.size()); pos |= pos + 1) {
f[pos] += val;
}
}
int main() {
#ifdef _DEBUG
freopen("input.txt", "r", stdin);
// freopen("output.txt", "w", stdout);
#endif
int n;
cin >> n;
vector<pair<int, int>> p(n);
for (auto &pnt : p) cin >> pnt.first;
for (auto &pnt : p) cin >> pnt.second;
sort(p.begin(), p.end());
vector<int> vs;
for (auto