zoukankan      html  css  js  c++  java
  • [差分数组]JZOJ 3187 的士

    Description

    Bessie为农场上的其他奶牛提供的士服务。奶牛们在一条长为M(1<=M<=1,000,000,000)的栅栏的不同位置上。不幸的是,它们厌倦了它们现在所在的位置而想要去栅栏上其他的位置。Bessie必须把她每一个朋友从它们各自的起始地接上车然后送它们到目的地。但Bessie的车太小了,所以她每次只能运送一只奶牛。奶牛们上车下车是瞬间的事情。

        为了省油钱,Bessie想要使她的驾驶量最小。给出N只奶牛(1<=N<=100,000)每一只的起始地和目的地,计算Bessie最少需要的驾驶量。Bessie意识到她需要偶尔把牛放在某一个地方而不是把它送到目的地才能省油钱。

        Bessie在栅栏最左端(位置0)开始工作,而且必须在最右端(位置M)结束她的工作。
     

    Input

    第一行输入正整数N,M

        接下来N行,每行包括两个整数s_i,t_i(0<=s_i,t_i<=M),表示第i只奶牛的起始地和目的地。

    Output

    输出一行,Bessie最少需要的驾驶量。(注意最终结果可能会超出32位整数)
     

    Sample Input

    2 10 
    0 9 
    6 5

    Sample Output

    12
     

    Data Constraint

    1<=N<=100,000
     

    Hint

    在长度为10的栅栏上,有两只奶牛需要被运送。第一只想要从位置0(Bessie开始工作的地方)到位置9。第二只想要从位置6到位置5。Bessie要把第一只牛从位置0送到位置6,再把第二只牛接上来送到它的目的地位置5,然后再把第一只牛接送到它的目的地位置9,最后驾驶到栅栏的最后端结束工作。

    分析

    我们可以发现,对于一个区间[l,r],l左侧想要去到r右侧的有a个,r右侧想要去到l左侧的有b个,那么这个区间将要被经过(r-l+1)*(2*a-1)次或(r-l+1)*(2*b+1)次

    为什么是“或”而不是“和”呢?我们发现当a>b时,我们每次把a中的一个运过去时,可以顺便把b的一个带过来,所以只用做(r-l+1)*(2*a-1)次,同理b>a也差不多

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    using namespace std;
    typedef long long ll;
    const int N=1e5+10;
    int a[2*N],s[N][2];
    int cnt;
    int n,m;
    ll ans,L[2*N],R[2*N];
    
    int main() {
        scanf("%d%d",&n,&m);
        for (int i=1;i<=n;i++) {
            scanf("%d%d",&s[i][0],&s[i][1]);
            a[++cnt]=s[i][0],a[++cnt]=s[i][1];
        }
        sort(a+1,a+cnt+1);
        cnt=unique(a+1,a+cnt+1)-(a+1);
        for (int i=1;i<=n;i++) {
            int l=lower_bound(a+1,a+cnt+1,s[i][0])-a,r=lower_bound(a+1,a+cnt+1,s[i][1])-a;
            if (l<r) L[l]++,L[r]--;
            else R[l]++,R[r]--;
        }
        for (int i=1;i<=cnt;i++) L[i]+=L[i-1];
        for (int i=cnt;i>=1;i--) R[i]+=R[i+1];
        ans=m-(a[cnt]-a[1]);
        for (int i=2;i<=cnt;i++) {
            int l=L[i-1],r=R[i];
            if (l>r) ans+=1ll*(2*l-1)*(a[i]-a[i-1]);
            else ans+=1ll*(2*r+1)*(a[i]-a[i-1]);
        }
        printf("%lld",ans);
    }
    View Code
    在日渐沉没的世界里,我发现了你。
  • 相关阅读:
    最短路问题之Dijkstra算法
    最短路问题之Bellman-ford算法
    最小生成树之Kruskal(克鲁斯卡尔)算法
    二分图问题
    七桥问题与欧拉道路
    拓扑排序
    八连通块
    四连通检测
    USACO19DEC题解
    1206 雅礼集训D2题解
  • 原文地址:https://www.cnblogs.com/mastervan/p/10770608.html
Copyright © 2011-2022 走看看