博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【二分答案+单调队列】寻找段落
阅读量:7049 次
发布时间:2019-06-28

本文共 1419 字,大约阅读时间需要 4 分钟。

二分答案+单调队列前缀和维护

每次二分一个平均值k, 序列中的数全部减去k, 如果序列中存在长度在[s, t]中且和超过0的子序列, 则证明仍然有更大的平均值, 到[mid, r]中找, 反之, 则到[l, mid] 中找 (这个操作用单调队列维护)

i - s > q[tail] 且 sum[i - s]  < sum[q[tail]] 说明i-s这个点更不容易超出[s, t] 的范围, 且构成的子序列和更大, 所以生存能力更强orzorz

详见代码qwq

1 #include
2 #include
3 #define sz 100010 4 #define dou double 5 using namespace std; 6 int n, s, t; 7 int q[sz], b[sz]; 8 dou l, r, mid, ans = 0; 9 dou a[sz], sum[sz];10 bool check(dou x) {11 int head = 1, tail = 0;12 for(int i = 1; i <= n; i++) 13 a[i] = (dou)b[i] - x;14 for(int i = 1; i <= n; i++)15 sum[i] = sum[i - 1] + a[i];16 for(int i = 1; i <= n; i++) {17 if(i >= s) {18 while(tail >= head && sum[i - s] < sum[q[tail]]) tail--;//很妙的词,生存能力更强orz 19 q[++tail] = i - s;20 }21 if(head <= tail && q[head] < i - t) head++;22 if(head <= tail && sum[i] - sum[q[head]] >= 0) return true; 23 }24 return false;25 }26 int main() {27 scanf("%d%d%d", &n, &s, &t);28 for(int i = 1; i <= n; i++)29 scanf("%d", &b[i]);30 ans = l = -10000, r = 10000;31 while(r - l > 1e-5) {32 dou mid = (l + r) / 2;33 if(check(mid)) {34 ans = mid;35 l = mid + 1e-5;36 }37 else r = mid - 1e-5;38 }39 printf("%.3lf\n", ans);40 return 0;41 }

 

转载于:https://www.cnblogs.com/Hwjia/p/9899528.html

你可能感兴趣的文章
京东手机webapp商城
查看>>
POSIX 消息队列 之 参数说明
查看>>
【IOS】Target membership
查看>>
20141123
查看>>
EF架构~EF6配置需要注意的几个地方
查看>>
Android英文文档翻译系列(4)——PopupWindow
查看>>
SQL_sql的简单查询
查看>>
详解CSS网页布局中默认字体样式
查看>>
【2012.1.24更新】不要再在网上搜索eclipse的汉化包了!
查看>>
java日历
查看>>
查看linux系统的开机时间/重启历史记录
查看>>
监控页面所有 ajax请求
查看>>
算法系列15天速成——第一天 七大经典排序【上】
查看>>
Javascript之旅——第三站:几个需要注意的运算符
查看>>
我在实习的英文表达
查看>>
多种方法求解八数码问题
查看>>
贪心算法
查看>>
数据流图的画法
查看>>
[SAP ABAP开发技术总结]业务对象和BAPI
查看>>
Win8应用开发 入门篇(三) UX交互导航模式
查看>>