Luogu P1419 尋找段落

2022-07-07 09:12:11 字數 1410 閱讀 9430

我又復活啦!!!

這裡給定乙個長度為\(n\)的序列\(a\),定義\(a_i\) 為第\(i\)個元素的價值。現在需要找出序列中最有價值的「段落」。段落的定義是長度在\([s, t]\)之間的連續序列。最有價值段落是指平均值最大的段落。

段落的平均值等於段落總價值除以段落長度

第一行乙個整數\(n\),表示序列長度。

第二行兩個整數\(t\)和\(t\),表示段落長度的範圍,在\([s, t]\)之間。

第三行到第\(n+2\)行,每行乙個整數表示每個元素的價值指數。

乙個實數,保留 33 位小數,表示最優段落的平均值。

3

2 23

-12

1.000
平均值的題目有很多都與二分有關係

答案具有二分性,試一下二分。

若\(s\)陣列表示\(a\)陣列的字首和。\(mid\)表示二分中間值。

那麼,我們就是要找到乙個\(i\),\(j\)使\((s[i] - s[j]) / (i - j)) \ge mid,(i > j且s \le i - j \le t) \implies s[i] - mid * i \ge s[j] - mid * j\)。

令\(t[i] = s[i] - mid * i\),我們就是要找到一對\(i,j(i > j且s \le i - j \le t)\),使得\(t[i] > t[j]\)。這可以通過單調佇列做到,參考luogu p1886。遍歷每乙個\(t[i]\),尋找\(min(t[i - s]...t[i - t])\)即可。

\(code\)

#include using namespace std;

const int maxn = 1e6 + 10;

int que[maxn],n,s,t,head,tail;

int a[maxn];

double t[maxn];

bool judge(double cur)

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

que[++tail] = i - s;

} if (head <= tail && que[head] < i - t) head++;

if (t[i] >= t[que[head]] && head <= tail) return true;

} return false;

}int main()

double l = -1e4,r = 1e4 + 10;

while (r - l > 0.00001)

printf("%.3lf",l);

return 0;

}

Luogu P1419尋找段落(單調佇列)

題目鏈結 不知為何狀態突然奇差無比,按說這題本來應該是水題的,但不僅不會做,還比著題解爆零五次 二分平均值 想到了 單調佇列維護最大區間和 想到了但是不會,為什麼我不會?include include include include include define maxn 200020 define...

P1419 尋找段落

題目鏈結 思路 首先二分答案,即 二分最大平均值。我們將a全部減去mid,問題轉化為判斷是否存在乙個長度在s t範圍內的區間它的和為正,如果有說明還有更大的平均值。用字首和和單調佇列維護。然後用單調佇列求出sum i min sum i t sum i s 然後判斷是否大於0即可。include i...

洛谷 P1419 尋找段落

給定乙個長度為n的序列a i,定義a i 為第i個元素的價值。現在需要找出序列中最有價值的 段落 段落的定義是長度在 s,t 之間的連續序列。最有價值段落是指平均值最大的段落,段落的平均值 段落總價值 段落長度。輸入格式 第一行乙個整數n,表示序列長度。第二行兩個整數s和t,表示段落長度的範圍,在 ...