Codeforces Round #624 (Div. 3) F Moving Points(离散化+树状数组)

F. Moving Points

time limit per test

2 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

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

Input

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.

Output

Print one integer — the value ∑1≤i

Examples

input

Copy

3
1 3 2
-100 2 3

output

Copy

3

input

Copy

5
2 1 4 3 5
2 2 2 3 4

output

Copy

19

input

Copy

2
2 1
-3 0

output

Copy

0
#include
using namespace std;
const int N = 2e5 + 10;
long long z[N], f[N], zsum[N], fsum[N];
int lowbit(int x) {
	return x & (-x);
}
long long sum(int x,long long d[]) {
	long long res = 0;
	while (x) {
		res += d[x];
		x -= lowbit(x);
	}
	return res;
}
void add(int x,int k, long long d[]) {
	while (x < N) {
		d[x] += k;
		x += lowbit(x);
	}
}
struct fuck {
	int p, v;
}sp[N];
bool cmp(fuck a, fuck b) {
	return a.p < b.p;
}
int sor[N]; int n;
int main(){
	ios::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);
	cin >> n;
	for (int i = 1; i <= n; i++) {
		cin >> sp[i].p;
	}
	for (int i = 1; i <= n; i++) {
		cin >> sp[i].v;
		sor[i] = sp[i].v;
	}
	sort(sor + 1, sor + 1 + n);
	sort(sp + 1, sp + 1 + n, cmp);
	long long ans = 0;
	for (int i = 1; i <= n; i++) {
		if (sp[i].v < 0) {
			int pv = lower_bound(sor + 1, sor + 1 + n, sp[i].v) - sor;
			ans += 1LL * sum(pv, fsum) * sp[i].p - sum(pv, f);
			add(pv, sp[i].p, f);
			add(pv, 1, fsum);
		}
		else {
			int pv = lower_bound(sor + 1, sor + 1 + n, sp[i].v) - sor;
			ans += 1LL * sum(N - 1, fsum) * sp[i].p - sum(N - 1, f);
			ans += 1LL * sum(pv, zsum) * sp[i].p - sum(pv, z);
			add(pv, sp[i].p, z);
			add(pv, 1, zsum);
		}
	}
	cout<

 

你可能感兴趣的:(数据结构)