F. Moving Points
time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
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
inputCopy
3
1 3 2
-100 2 3
outputCopy
3
inputCopy
5
2 1 4 3 5
2 2 2 3 4
outputCopy
19
inputCopy
2
2 1
-3 0
outputCopy
0
題意:
給出一些在座標軸上的質點,帶着位置和速度的屬性,求 兩兩質點最小dis(i,j)之和。
思路:
- 本來是不想寫的,因爲這個是賽後才補上的套路題,但翻了翻網上的題解幾乎都是直接貼代碼,索性就開一篇以後自己可以回顧。
- 問題求的是最小距離之和,可以發現這個距離只有兩種情況:
- 一種是 xi<xj && vi<vj 這樣 i 永遠追不上j 所以 min dis= xj - xi
- 其他情況 便是 i 能夠與 j 重合 ,這種情況 min dis = 0
- 每個點對答案的貢獻= 比自己小的點數*xi - 比自己小的點的座標和
- 可以發現除了xi 其他兩個變量都與和有關,這個時候就要聯想到樹狀數組or線段樹。
- 所以可以把點集排個序,再把速度離散化,依次遍歷即可。
代碼:
#include<bits/stdc++.h>
#define IOS ios::sync_with_stdio(false);cin.tie(0)
#define ll long long
//#define ll unsigned long long
#define inf 0x3f3f3f3f
#define mod 1000000007
#define eps 1e-6
#define pi acos(-1)
#define myit set<ll>::iterator
#define mysets multiset<ll>
#define myits multiset<ll>::iterator
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define lowbit(x) (x&(-x))
#define mp make_pair
#define pb push_back
#define si size()
#define E exp(1.0)
#define fixed cout.setf(ios::fixed)
#define fixeds(x) setprecision(x)
using namespace std;
inline ll read(){
ll s=0,w=1;
char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
return s*w;
}
void put1(){ puts("YES") ;}
void put2(){ puts("NO") ;}
void put3(){ puts("-1"); }
using namespace std;
ll qpf(ll a, ll b, ll p)
{ll ret = 0;while(b){if(b & 1) ret = (ret + a) % p;
a = (a + a) % p;b >>= 1;}return ret % p ;}
ll qp(ll a, ll n, ll p)
{ll ret = 1;while(n){if(n & 1) ret = qpf(ret, a, p);a = qpf(a, a, p);
n >>= 1;}return ret % p ;}
const int manx=2e5+5;
struct node{
ll x,v;
}a[manx];
bool cmp(node a,node b){return a.x<b.x;}
ll maps[manx],s[manx][2];
ll ans=0,n;
void add(ll x, ll val){
while(x<=n){
s[x][0]++;
s[x][1]+=val;
x+=lowbit(x);
}
}
ll gets(ll x,ll k){
ll res=0;
while(x){
res+=s[x][k];
x-=lowbit(x);
}
return res;
}
int main()
{
n=read();
for(int i=1;i<=n;i++) a[i].x=read();
for(int i=1;i<=n;i++) a[i].v=maps[i]=read();
sort(a+1,a+1+n,cmp);
sort(maps+1,maps+1+n);
ll m=unique(maps+1,maps+1+n)-maps-1;
ll ans=0;
for(int i=1;i<=n;i++){
ll x=lower_bound(maps+1,maps+1+m,a[i].v)-maps;
ans+=a[i].x*gets(x,0)-gets(x,1);
add(x,a[i].x);
}
cout<<ans<<endl;
return 0;
}