題目連接spa
思路:code
首先二分答案,即:二分最大平均值。隊列
咱們將a所有減去mid,問題轉化爲判斷是否存在一個長度在s~t範圍內的區間它的和爲正,若是有說明還有更大的平均值。get
用前綴和和單調隊列維護。string
而後用單調隊列求出sum[i]-min(sum[i-t]~sum[i-s]),而後判斷是否大於0便可。it
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int MAXN = 1e5 + 5; int n; int s,t; int a[MAXN]; double sum[MAXN]; inline int read() { int k = 0, f = 1; char ch = getchar(); while (ch < '0' || ch > '9') { if (ch == '-') f = -1; ch = getchar(); } while (ch >= '0' && ch <= '9') { k = (k << 1) + (k << 3) + (ch & 15); ch = getchar(); } if (f == -1) k = ~k + 1; return k; } int head = 1,tail = 0,q[MAXN]; bool check(double mid){ memset(q,0,sizeof(q)); memset(sum,0,sizeof(sum)); for(int i = 1 ; i <= n ; i++) sum[i] = sum[i - 1] + double(a[i]) - mid; head = 1,tail = 0; for(int i = s ; i <= n ; i++){ while(head <= tail && sum[q[tail]] > sum[i - s]) tail--; q[++tail] = i - s; while(head <= tail && q[head] < i - t) head++; if(head <= tail && sum[i] - sum[q[head]] >= 0) return true; } return false; } int main(){ n = read(),s = read(),t = read(); for (int i = 1 ; i <= n ; i++) a[i] = read(); double l = -10000.0,r = 10000.0; while(r - l > 1e-4){ double mid = (l + r) / 2.0; if (check(mid) == true) l = mid; else r = mid; } printf("%.3lf",l); return 0; }