常數巨大警告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 為每乙個景...