• Codeforces 1311F


    题目大意:

    坐标轴上有 n 个点,每个点有初始位置 x 与速度 v

    问在运动过程中,点两两之间最小距离之和

    2<=n<=200000  1<=x<=1e8  -1e8<=v<=1e8

    解题思路:

    两两点情况共三种:

      1、左边的点速度小于右边的点:这种情况距离会随运动时间增加而增加,最小距离即初始距离

      2、左边的点速度等于右边的点:这种情况距离不变,最小距离即初始距离

      3、左边的点速度大于右边的点:这种情况距离会随运动时间增加而先减小后增加,最小距离为0,不需要考虑

    所以可以按照 x 从小到大循环每个点,对答案的贡献为与左边每个速度小于等于自己的点的距离差之和

    对于点的距离差之和,可以由 当前点的x * 左边点的个数 - 左边点的x之和得到

    所以很容易想到用两个树状数组,一个维护个数,一个维护x之和

    则树状数组的下标可以使用 v

    但是因为v的范围为±1e8,点的个数只有2e5,所以先对 v 进行离散化

    然后在循环时,先执行答案增加,再对树进行维护

    (280ms/2000ms)

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int INF=0x3f3f3f3f;
    
    int n,tree[200050];//tree维护个数
    ll tree2[200050];//tree2维护x之和
    int lowbit(int x){
        return x&(-x);
    }
    void add(int in1){
        while(in1<=n){
            tree[in1]++;
            in1+=lowbit(in1);
        }
    }
    int sum(int in){
        int r=0;
        while(in>0){
            r+=tree[in];
            in-=lowbit(in);
        }
        return r;
    }
    void add2(int in1,ll in2){
        while(in1<=n){
            tree2[in1]+=in2;
            in1+=lowbit(in1);
        }
    }
    ll sum2(ll in){
        ll r=0;
        while(in>0){
            r+=tree2[in];
            in-=lowbit(in);
        }
        return r;
    }
    
    struct node{
        int x,v;
        bool operator < (const node& a) const{
            return x<a.x;
        }//按x升序排序
    }ar[200050];
    int y[200050];
    
    void solve(){
        cin>>n;
        int i;
        for(i=1;i<=n;i++)
            cin>>ar[i].x;
        for(i=1;i<=n;i++){
            cin>>ar[i].v;
            y[i]=ar[i].v;
        }
        sort(y+1,y+1+n);
        for(i=1;i<=n;i++)
            ar[i].v=lower_bound(y+1,y+1+n,ar[i].v)-y;//离散化
        sort(ar+1,ar+1+n);
        
        ll ans=0;
        for(i=1;i<=n;i++){
            ans+=1LL*sum(ar[i].v)*ar[i].x-sum2(ar[i].v);
            add(ar[i].v);
            add2(ar[i].v,ar[i].x);
        }
        cout<<ans<<'
    ';
    }
    int main(){
        ios::sync_with_stdio(0);
        cin.tie(0);cout.tie(0);
        solve();
        return 0;
    }
  • 相关阅读:
    硬件设计问题——持续更新
    PCB设计资源整理
    PCB层叠设计和电源分割
    PCB设计技巧
    铜厚电流、Layout 3W原则 20H原则 五五原则
    final关键字
    面向对象——继承与组合
    面向对象——继承
    this总结
    static总结
  • 原文地址:https://www.cnblogs.com/stelayuri/p/12463842.html
Copyright © 2020-2023  润新知