- P1419 寻找段落
- 题意:给定一个长度为n的序列a_i,定义a[i]为第i个元素的价值。现在需要找出序列中最有价值的“段落”。
- 段落的定义是长度在[S,T]之间的连续序列。最有价值段落是指平均值最大的段落,
- 段落的平均值=段落总价值/段落长度。
- 思路:我们将a全部减去mid,问题转化为判断是否存在一个长度在s~t范围内的区间它的和为正。
- 如果有说明还有更大的平均值。用前缀和单调队列维护。
- 然后用单调队列求出sum[i]-min(sum[i-t]~sum[i-s]),然后判断是否大于0即可。
-
#include<bits/stdc++.h> using namespace std; #define maxn 123456 int n,m,s,t; double a[maxn],l,r,mid,b[maxn]; bool ok(double x) { deque<int>q; q.clear(); for(int i=1; i<=n; i++) b[i]=b[i-1]+a[i]-x; for(int i=s; i<=n; i++) { while(!q.empty()&&b[q.back()]>b[i-s])q.pop_back(); q.push_back(i-s); while(!q.empty()&&i-q.front()>t)q.pop_front(); if(!q.empty()&&b[i]-b[q.front()]>=0)return 1; } return 0; } int main() { scanf("%d%d%d",&n,&s,&t); for(int i=1; i<=n; i++) scanf("%lf",&a[i]); r=10000; l=-10000; while(1e-5<r-l) { mid=(l+r)/2; if(ok(mid))l=mid; else r=mid; } if(ok(r))l=r; printf("%.3lf\n",l); return 0; }
P1419 寻找段落 -二分答案-单调队列
最新推荐文章于 2023-09-23 10:39:09 发布