F. Moving Points

 

 

思路:

初中的“追及问题” 

假设 Xi 在 Xj 的左侧,并且速度 Vi 大于 Vj,那么 Xi 肯定可以追上 Xj   即 d(i,j) = 0

          如果速度 Vi <= Vj ,那么 d(i,j) = abs(Xi - Xj)

所以答案就是:

ans+=(数组中位于当前点前面的点的数量(速度小于当前点速度的点的数量)×当前点的位置)- 前面所有点的位置值的和。

我们可以维护速度 V 的序列,然后每次去查询、更新每个点的贡献   

这题还需要注意速度 V 需要进行离散化

#include <algorithm>
#include <string>
#include <string.h>
#include <vector>
#include <map>
#include <stack>
#include <set>
#include <queue>
#include <math.h>
#include <cstdio>
#include <iomanip>
#include <time.h>
#include <bitset>
#include <cmath>
#include <sstream>
#include <iostream>

#define LL long long
#define INF 0x3f3f3f3f
#define ls nod<<1
#define rs (nod<<1)+1

const double eps = 1e-10;
const int maxn = 2e5 + 10;;
const LL mod = 1e9 + 7;

int sgn(double a){return a < -eps ? -1 : a < eps ? 0 : 1;}
using namespace std;

int b[maxn];
struct node {
    int x,v;
}a[maxn];
bool cmp(node t1,node t2) {
    return t1.x<t2.x;
}

struct segment_tree {
    LL val,num;
}tree[maxn << 2];


void modify(int l,int r,int k,LL v,int nod) {
    if (l == r) {
        tree[nod].val += v;
        tree[nod].num += 1;
        return ;
    }
    int mid = (l + r) >> 1;
    if (k <= mid)
        modify(l,mid,k,v,ls);
    else
        modify(mid+1,r,k,v,rs);
    tree[nod].val = (tree[ls].val + tree[rs].val);
    tree[nod].num = (tree[ls].num + tree[rs].num);
}


LL query(int l,int r,int ql,int qr,int nod) {
    if (ql <= l && qr >= r)
        return tree[nod].val;
    int mid = (l + r ) >> 1;
    LL ans = 0;
    if (ql <= mid)
        ans += query(l,mid,ql,qr,ls);
    if (qr > mid)
        ans += query(mid+1,r,ql,qr,rs);
    return ans;
}

LL query2(int l,int r,int ql,int qr,int nod) {
    if (ql <= l && qr >= r)
        return tree[nod].num;
    int mid = (l + r ) >> 1;
    LL ans = 0;
    if (ql <= mid)
        ans += query2(l,mid,ql,qr,ls);
    if (qr > mid)
        ans += query2(mid+1,r,ql,qr,rs);
    return ans;
}

int main() {
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i].x);
    }
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i].v);
        b[i]=a[i].v;
    }
    sort(a+1,a+1+n,cmp);
    sort(b+1,b+1+n);
    int len=unique(b+1,b+1+n)-b-1;
    LL ans=0;
    for(int i=1;i<=n;i++){
        int v = lower_bound(b+1,b+1+len,a[i].v)-b;
        //cout << query2(1,n,1,v,1) << " " << query(1,n,1,v,1) << endl;
        ans += query2(1,n,1,v,1)*a[i].x-query(1,n,1,v,1);
        modify(1,n,v,a[i].x,1);
    }
    printf("%lld\n",ans);
    return 0;
}

 

posted @ 2020-03-01 21:41  _Ackerman  阅读(281)  评论(0编辑  收藏  举报