BZOJ2388 旅行規劃

2022-05-09 16:26:41 字數 3198 閱讀 2342

[bzoj2388]旅行規劃

試題描述

oivillage是乙個風景秀美的鄉村,為了更好的利用當地的旅遊資源,吸引遊客,推動經濟發展,xkszltl決定修建了一條鐵路將當地n個最著名的經典連線起來,讓遊客可以通過火車從鐵路起點(1號景點)出發,依次遊覽每個景區。為了更好的評價這條鐵路,xkszltl為每乙個景區都哦賦予了乙個美觀度,而一條旅行路徑的價值就是它所經過的景區的美觀度之和。不過,隨著天氣與季節的變化,某些景點的美觀度也會發生變化。

xkszltl希望為每位旅客提供最佳的旅行指導,但是由於遊客的時間有限,不一定能遊覽全部景區,然而他們也不希望旅途過於短暫,所以每個遊客都希望能在某乙個區間內的車站結束旅程,而xkszltl的任務就是為他們選擇乙個終點使得旅行線路的價值最大。可是當地的景點與前來觀光的旅客實在是太多了,xkszltl無法及時完成任務,於是找到了準備虐殺noi2011的你,希望你能幫助他完成這個艱鉅的任務。

輸入

第一行給出乙個整數n,接下來一行給出n的景區的初始美觀度。

第三行給出乙個整數m,接下來m行每行為一條指令:

1.         0 x y k:表示將x到y這段鐵路邊上的景區的美觀度加上k;

2.         1 x y:表示有一名旅客想要在x到y這段(含x與y)中的某一站下車,你需要告訴他最大的旅行價值。

輸出

對於每個詢問,輸出乙個整數表示最大的旅行價值。

輸入示例

5

18 -8

3 -731

1501

3612

4

輸出示例

9

22

資料規模及約定

對於20%的資料,n,m≤3000;

對於40%的資料,n,m≤30000;

對於50%的資料,n,m≤50000;

另外20%的資料,n,m≤100000,修改操作≤20;

對於100%的資料,n,m≤100000。

題解

這題就是讓維護區間最大字首和(字首和左端點為 1)。那麼我們不妨就維護這個字首和。

那麼區間 [l, r] 的修改操作就變成了從第 l 個數開始,依次給每個位置加上 k, 2k, 3k, ... , (r-l+1)k。

查詢操作就是詢問區間最大值。

我們對序列分塊。考慮修改操作,對於整塊的我們打兩個懶標記:addv[i] 表示這一塊中的所有數增加 addv[i] 的值;k[i] 表示這一塊中增加的等差數列的公差,即這一塊中的元素在加完 addv[i] 後依次要加上 k[i], 2k[i], 3k[i], ... , siz · k[i]。再想想詢問如何處理,對於整塊的詢問相當於就是找到 max(st[i] 和 en[i] 表示第 i 個塊的起始和終點位置),我們發現如果把 (x - st[i] + 1, s[x]) 當作座標系上的點,那麼詢問就相當於用一條斜率為 -k[i] 的直線去碰那個點,要求找到最大的截距,解決這個問題維護凸包即可。

注意當 k[i] 和 addv[i] 變化時(即整塊都被修改),不需要重新維護凸包形態(想一想,為什麼)。

#include #include #include #include #include #include #include using namespace std;

const int buffersize = 1 << 16;

char buffer[buffersize], *head, *tail;

inline char getchar()

return *head++;

}int read()

while(isdigit(c))

return x * f;

}#define maxn 100010

#define maxbl 320

#define oo (1ll << 60)

#define ll long long

int n, cb, st[maxbl], en[maxbl], blid[maxn];

ll sa[maxn], addv[maxbl], k[maxbl], cp[maxbl];

struct vec

vec(ll _, ll __): x(_), y(__) {}

vec operator + (const vec& t) const

vec operator - (const vec& t) const

ll operator ^ (const vec& t) const

} poly[maxbl][maxbl];

void pushdown(int bl)

void build_poly(int bl)

return ;

}void update(int ql, int qr, int k)

else

} for(int i = blid[qr] + 1; i <= cb; i++) addv[i] += (ll)k * (qr - ql + 1);

return ;

}ll getans(int bl, int p)

ll query(int ql, int qr)

int b = blid[ql];

pushdown(b); build_poly(b);

for(int i = ql; i <= en[b]; i++) ans = max(ans, sa[i]);

b = blid[qr];

pushdown(b); build_poly(b);

for(int i = st[b]; i <= qr; i++) ans = max(ans, sa[i]);

for(int i = blid[ql] + 1; i <= blid[qr] - 1; i++)

ans = max(ans, getans(i, l)); }

return ans;

}int main()

for(int i = 1; i <= cb; i++) build_poly(i);

int q = read();

while(q--)

else }

return 0;

}

分塊打起來好爽 ^_^

BZOJ2388 旅行規劃

分塊,每一塊維護字首和,觀察發現,一次區間加操作對於 l 前,r後的區間裡相對的大小關係沒有影響,對於 l r 裡,將每個位置放在平面內作為乙個點 i si 那麼相當於給區間裡加了乙個斜率。每個塊維護乙個凸包 上凸下凸應該都可以,下文以上凸為例 如果這個塊被完整覆蓋,就打個斜率的標記,否則暴力重構凸...

bzoj2388 旅行規劃

凸包好題 我一開始想的是線段樹或平衡樹維護最大字首和,但是區間修改很噁心,後來想分塊,發現貌似可以做,修改的話,中間的塊打標記,兩邊的暴力重構,查詢的話就是整塊二分斜率為零的地方,邊上的暴力查詢。o nsqrt n log n 1 include 2 include 3 include 4 incl...

BZOJ2388 旅行規劃

bzoj2388 旅行規劃 又是一道氪金題。bzoj 氪金無極限。附上大美洛谷的題面 洛谷p4192 旅行規劃 oivillage是乙個風景秀美的鄉村,為了更好的利用當地的旅遊資源,吸引遊客,推動經濟發展,xkszltl決定修建了一條鐵路將當地n個最著名的經典連線起來,讓遊客可以通過火車從鐵路起點 ...