【单调队列】【3-21个人赛】【problmeB】
Problem B
Time Limit : 4000/2000ms (Java/Other) Memory Limit : 65535/32768K (Java/Other)
Total Submission(s) : 170 Accepted Submission(s) : 29
Font: Times New Roman | Verdana | Georgia
Font Size: ← →
Problem Description
例如6个亮度为: 1, -3, 5, 1, -2, 3的灯泡,
当A=2,B=2或3时 S=5+1=6
当A=3,B=4时 S=5+1+(-2)+3=7
Input
接下来为T组数组,每组的格式为:
第一行三个整数N,A,B(1<=A<=B<=N<=500000)。
第二行为N个整数,每个整数用空格隔开,表示这N个灯泡的亮度。|亮度|<=10000。
Output
Sample Input
2
6 2 2
1 -3 5 1 -2 3
6 3 4
1 -3 5 1 -2 3
Sample Output
6
7
枚举连续序列的初始点 并找到【初始点+A-1,初始点+B-1】区间中的sum[i]的最大值 更新ANS即可
复杂度N*(B-A)
但是我们可以看出 在找最大值时 这个区间是固定不动的,而且随着枚举初始点向左移,所以可以用单调队列来维护这个区间最大值
是单调队列的一个常用法
单调队列介绍在这里
http://blog.csdn.net/justmeh/article/details/5844650
1.不加二分
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <ctime>
#include <algorithm>
#include <iostream>
#include <sstream>
#include <string>
#define oo 0x13131313
const int maxn=500000+5;
using namespace std;
struct node
{
long long num;
int pos;
};
long long N,A,B;
long long a[maxn],sum[maxn];
node queue[maxn];
int s=1,t=0;
void init()
{
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
}
void input()
{
s=1;t=0;
scanf("%d%d%d",&N,&A,&B);
for(int i=1;i<=N;i++)
{
scanf("%I64d",&a[i]);
sum[i]=sum[i-1]+a[i];
}
}
void PUSH(long long aa,int bb)
{
while(t!=s-1&&queue[t].num<=aa) t--;
queue[++t].num=aa,queue[t].pos=bb;
}
void solve()
{
long long ans;
for(int i=A;i<=B;i++)
PUSH(sum[i],i);
ans=queue[s].num-sum[0];
for(int i=2;i+A-1<=N;i++)
{
if(i+B-1<=N)
PUSH(sum[i+B-1],i+B-1);
while(queue[s].pos<i+A-1)
s++;
if(ans<queue[s].num-sum[i-1])ans=queue[s].num-sum[i-1];
}
printf("%I64d\n",ans);
}
int main()
{
// init();
int T;
cin>>T;
while(T--)
{
input();
solve();
}
return 0;
}
2.加二分
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <ctime>
#include <algorithm>
#include <iostream>
#include <sstream>
#include <string>
#define oo 0x13131313
const int maxn=500000+5;
using namespace std;
struct node
{
long long num;
int pos;
};
long long N,A,B;
long long a[maxn],sum[maxn];
node queue[maxn];
int s=1,t=0;
void init()
{
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
}
void input()
{
s=1;t=0;
scanf("%d%d%d",&N,&A,&B);
for(int i=1;i<=N;i++)
{
scanf("%I64d",&a[i]);
sum[i]=sum[i-1]+a[i];
}
}
int FIND(int s,int t,int p)
{
int m;
while(s<t)
{
int m=(s+t)/2;
if(queue[m].num<p) t=m;
else s=m+1;
}
if(queue[s].num<=p) return s-1;
else return s;
}
void PUSH(long long aa,int bb)
{
int k=0;
if(s>t)
queue[++t].num=aa,queue[t].pos=bb;
else {
t=FIND(s,t,aa);
queue[++t].num=aa,queue[t].pos=bb;
}
}
void solve()
{
long long ans;
for(int i=A;i<=B;i++)
PUSH(sum[i],i);
ans=queue[s].num-sum[0];
for(int i=2;i+A-1<=N;i++)
{
if(i+B-1<=N)
PUSH(sum[i+B-1],i+B-1);
while(queue[s].pos<i+A-1)
s++;
if(ans<queue[s].num-sum[i-1])ans=queue[s].num-sum[i-1];
}
printf("%I64d\n",ans);
}
int main()
{
// init();
int T;
cin>>T;
while(T--)
{
input();
solve();
}
return 0;
}
【单调队列】【3-21个人赛】【problmeB】的更多相关文章
- 单调队列 && 斜率优化dp 专题
首先得讲一下单调队列,顾名思义,单调队列就是队列中的每个元素具有单调性,如果是单调递增队列,那么每个元素都是单调递增的,反正,亦然. 那么如何对单调队列进行操作呢? 是这样的:对于单调队列而言,队首和 ...
- Buying Feed, 2010 Nov (单调队列优化DP)
约翰开车回家,又准备顺路买点饲料了(咦?为啥要说"又"字?)回家的路程一共有 E 公里,这一路上会经过 K 家商店,第 i 家店里有 Fi 吨饲料,售价为每吨 Ci 元.约翰打算买 ...
- BZOJ 5281--[Usaco2018 Open]Talent Show(分数规划&单调队列&DP)
5281: [Usaco2018 Open]Talent Show Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 79 Solved: 58[Sub ...
- HDOJ 5289 Assignment 单调队列
维护一个递增的和递减的单调队列 Assignment Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Ja ...
- 【贪心/DP/单调队列】【CF1029B】Creating the Contest
Description 给你一个单调不下降的长度为n的序列,请你找出一个最长的子序列,满足找出的子序列中,\(A_i<=A_{i-1}~\times~2\),其中i为下标,A为找出的子序列.对于 ...
- HihoCoder1673 : 01间隔矩阵([Offer收割]编程练习赛41)(单调队列)
描述 给定一个N × M的01矩阵,小Hi希望从中找到一个01间隔的子矩阵,并且子矩阵的面积越大越好. 例如对于 0101010 1000101 0101010 1010101 0101010 在右侧 ...
- 算法复习——单调队列(sliding windows,ssoi)
题目: 题目描述 给你一个长度为 N 的数组,一个长为 K 的滑动的窗体从最左移至最右端,你只能见到窗口的 K 个整数,每次窗体向右移动一位,如下表:
- 洛谷P2569 [SCOI2010]股票交易(单调队列)
传送门 惭愧……这种题目都没看出来…… 首先,我们用$dp[i][j]$表示在第$i$天,手上有$j$股时的最大收益 第一,我们可以直接买股票,即$dp[i][j]=-j*AP_i$,这个直接计算即可 ...
- 洛谷P2219 [HAOI2007]修筑绿化带(单调队列)
传送门 啧……明明以前做到过这种类型的题结果全忘了…… 这种矩阵的,一般都是先枚举行,然后对列进行一遍单调队列,搞出右下角在每一行中合法位置时的最小权值 再枚举列,对行做一遍单调队列,用之前搞出来的最 ...
随机推荐
- Can you find it?(二分 二分+STL set map)
Can you find it? Time Limit : 10000/3000ms (Java/Other) Memory Limit : 32768/10000K (Java/Other) T ...
- 并行任务task
http://msdn.microsoft.com/zh-cn/library/dd537609(v=vs.110).aspx http://www.cnblogs.com/yangecnu/p/So ...
- LR实战之Discuz开源论坛——登录场景设计
以下是根据个人项目经验,对登录场景的设计,如下步骤: 一.打开Controller,添加登录脚本,选择“手动场景”,一般我们项目中经常使用的是“手动场景”类型设计,如图 二.在“设计”部分,设置场景的 ...
- url 的httppost 和http get ,put,delect
URL全称是资源描述符,我们可以这样认为:一个URL地址,它用于描述一个网络上的资源 ,而HTTP中的GET,POST,PUT,DELETE就对应着对这个资源的查 ,改 ,增 ,删 4个操作 .到这里 ...
- Git GUI简易使用教程
Git GUI简易使用教程:先上图~~~~~ 一. 先从添加文件开始讲(先上图): 1.选中要添加的文件,点击菜单栏的“提交”,选中“缓存为提交”,
- Winform单例模式与传值
单例模式(singleton)的意思就是只有一个实例.单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例.这个类称为单例类. 在多窗体界面中,如果要加入一个“关于”的窗体,用于显 ...
- 给远程桌面发送“Ctrl+Alt+Delete”组合键
首先: 在运行里,输入osk, 打开软键盘 然后,这时先按下本地键盘的Ctrl和Alt键,再点远程"软键盘"的"Del"键,成功发送"Ctrl+Alt ...
- mvc 客户端验证
@model MvcApplication1.Models.ViewClass @{ ViewBag.Title = "View2"; } @******引用这两个js实现客户端的 ...
- 解决升级Xcode后插件不能使用的问题
从Xcode 5开始,苹果要求加入UUID证书从而保证插件的稳定性.因此Xcode版本更新之后需要在插件的Info.plist文件中添加当前Xcode的UUID. 具体步骤如下: 1.获取Xcode的 ...
- 京东UED招聘web前端开发工程师(中/高级)
工作职责: 负责前端界面的构建和各类交互设计与实现: 前端样式和脚本的模块设计及优化: 协同后台开发人员完成项目: 负责新产品开发线前端工作(新产品.垂直站.移动端 .后端系统),可根据个人喜好及特长 ...