洛谷4192 旅行規劃(分塊 凸包)

2021-09-10 04:40:32 字數 1363 閱讀 9406

常數巨大警告qwq。

這道題其實題意很簡單,維護乙個序列,支援區間加,區間查詢最大字首和。

因為是查詢字首和所以直接維護乙個區間和,區間加就變成了區間加首項為k、公差為k的等差數列。

因為乙個等差數列+乙個等差數列還是乙個等差數列,所以這樣做是正確的。

所以就有兩個選擇:線段樹和分塊,但考慮到線段樹最後合併效率低下,所以選分塊(結果不知道為啥我的寫法常數賊大)

所以就開3個陣列,分別維護每個塊的等差數列首項、公差以及乙個add標記。

區間加的時候遇上整塊直接加在首項和公差上,查詢時直接返回(當前值+塊首項+公差*(當前位置-塊左端位置)+add)即可。

那麼怎麼查詢乙個整塊的字首和最大值?

如果將區間內所有點放在平面上,座標為(下標,字首和),那麼可以發現,最大的字首和所對應的點一定是在凸包上且一定是最高點,可以直接二分。

所以直接對每個塊暴力維護其凸包。

然後就是一些小細節。

注意每次update完後要在belong[y]+1~num的塊的add陣列打標記,因為前面的區間加對字首和有(y-x+1)*k的影響。

同時,要在將y+1~r[belong[y]]更新完後再維護凸包。

#includeusing namespace std;

typedef long long ll;

const int maxn=1e5+10;

const int maxm=350;

const ll inf=1e18;

int n,q;

ll a[maxn];

int num,siz;

int belong[maxn],l[maxm],r[maxm];

ll sx[maxm],gc[maxm],add[maxm];

int sta[maxm],top;

int cov[maxm][maxm];

int cnt[maxm];

ll read()

double xl(int x,int y)

void build(int x) }}

int main()

a[0]=a[n+1]=-inf;

fk();

q=read();

while(q--)

else

for(int i=belong[x]+1;ians=max(ans,query(i));

for(int i=x;i<=r[belong[x]];++i)

ans=max(ans,calc(i));

for(int i=l[belong[y]];i<=y;++i)

ans=max(ans,calc(i));

cout<} }

}

旅行規劃問題

問題描述 g 先生想獨自駕駛汽車從城市a 到城市b。從城市a 到城市b 的距離為d0 公里。汽車油箱的容量為c 公升。每公升汽油能行駛e 公里。出發點每公升汽油的 為p 元。從城市a到城市b 沿途有n 個加油站。第i 個加油站距出發點的距離為di,油價為每公升pi元。如何規劃才能使旅行的費用最省。程...

旅行規劃問題(貪心)

g 先生想獨自駕駛汽車從城市a到城市b。ab距離為dist 千公尺,油箱容量為c公升,每公升油行駛d千公尺,沿途有n個加油站,距a城的距離為si,油價分別為pi。a點時,郵箱為空,起點油價為p。求從a到b的最少費用。不能到達輸出 no solution 輸入 dsit c d p n 接下來n行輸入...

4212 旅行規劃(travel)

題意 oivillage 是乙個風景秀美的鄉村,為了更好的利用當地的旅遊資源,吸引遊客,推動經濟發展,xkszltl 決定修建了一條鐵路將當地 n nn 個最著名的經典連線起來,讓遊客可以通過火車從鐵路起點 1 11 號景點 出發,依次遊覽每個景區。為了更好的評價這條鐵路,xkszltl 為每乙個景...