差分陣列 JZOJ 3187 的士

2022-04-30 19:51:06 字數 1660 閱讀 1072

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 #include 

#include

using

namespace

std;

typedef

long

long

ll;const

int n=1e5+10

;int a[2*n],s[n][2

];int

cnt;

intn,m;

ll ans,l[

2*n],r[2*n];

intmain()

sort(a+1,a+cnt+1

); cnt=unique(a+1,a+cnt+1)-(a+1

);

for (int i=1;i<=n;i++)

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++)

printf(

"%lld

",ans);

}

view code

差分陣列概述

在網上講差分陣列的博文很少,也很難找到。一度以為差分陣列是傳播於小眾的神犇技巧所以一直放著沒有去研習。今天做了 bzoj1635後發現各路神犇都用差分陣列,本蒟卻傻傻寫了線段樹。對於序列a 取a i a i 1 為其差分陣列b i 的值,可以發現,a i bj 1 j i 如 對於序列 a b c ...

港口 差分陣列)

傳送門 思路 因為是區間加減,所以考慮差分陣列,題意變為 要求差分陣列d 2 d 3 d n d 2 d 3 dots d n d 2 d 3 d n 全為0.每次區間加或減會使差分陣列乙個加1,乙個減1,因為要用最小次數,所以每次操作最好產生有效貢獻,可知當為正數或負數的差分陣列變為0後,剩下我們...

差分陣列詳解

學習部落格 題目 來先看一道裸題,有n個數。m個操作,每一次操作,將x y區間的所有數增加z 最後有q個詢問,每一次詢問求出x y的區間和。思路 很明顯,直接用字首和無法快速滿足這個操作,所以我們就用到了差分陣列。設a陣列表示原始的陣列 設d i a i a i 1 1設f i f i 1 d i ...