HDU 6444 Neko's loop(单调队列)
The loop has a happy value aiai on the i−th(0≤i≤n−1)i−th(0≤i≤n−1) grid.
Neko likes to jump on the loop.She can start at anywhere. If she stands at i−thi−thgrid, she will get aiai happy value, and she can spend one unit energy to go to ((i+k)modn)−th((i+k)modn)−th grid. If she has already visited this grid, she can get happy value again. Neko can choose jump to next grid if she has energy or end at anywhere.
Neko has mm unit energies and she wants to achieve at least ss happy value.
How much happy value does she need at least before she jumps so that she can get at least ss happy value? Please note that the happy value which neko has is a non-negative number initially, but it can become negative number when jumping.
InputThe first line contains only one integer T(T≤50)T(T≤50), which indicates the number of test cases.
For each test case, the first line contains four integers n,s,m,k(1≤n≤104,1≤s≤1018,1≤m≤109,1≤k≤n)n,s,m,k(1≤n≤104,1≤s≤1018,1≤m≤109,1≤k≤n).
The next line contains nn integers, the i−thi−th integer is ai−1(−109≤ai−1≤109)ai−1(−109≤ai−1≤109)
OutputFor each test case, output one line "Case #x: y", where x is the case number (starting from 1) and y is the answer.Sample Input
2
3 10 5 2
3 2 1
5 20 6 3
2 3 2 1 5
Sample Output
Case #1: 0
Case #2: 2 题意:
给n个数字,当位于某一个数字时,可以得到这个数字的快乐值(可以重复获得),可以走m步,每次向后跳k格(循环),问快乐值要达到s,那么初始快乐值的最小值是多少?
思路:
这是2018ccpc的网络赛的题,暑假看着学长打比赛,在傍边连读题都帮不上。。。。 首先有一个显而易见的结论,对于某一个起点,跳着跳着就会回到起点,也就是说,一定存在循环节。
其次显而易见的,就是对于某一个数,只会存在于一个循环节中。
那么如果不考虑循环节的起点差异,找出所有循环节就是O(n)的。而实际上我们确实不用考虑,原因接下来再说。 我们可以轻易的算出某个循环节中所有元素的和--sum,因为存在负数,所以sum可能是负数。
再声明一下,len是循环节长度。
若sum<0,那么最多只需走min(m,len)步就可以得到最优解。
若sum>0,则需要先走m/len-1圈,为什么减一,其他博客有详解(博主太懒了),然后最多走m-(m/len-1)*len)步
先说这后面多出来的步数,假设是p步,这p步在sum<0时,p<=len,sum<0时,len<=p<=2*len。
为了求出这p步走出的最大值,我们使用单调队列。
首先求出循环节的前缀和sum,单调队列维护长度为p的滑窗的sum最小值。
维护 ans =( sum[i]-单调队列最小值 ) 的最大值就可以啦!
由于p的长度,要把循环节扩展3倍哟。 然后我们看到,这个单调队列,在ans取得最大值时,单调队列的最小值位置是不定的,所以很容易想到,不一定就是循环节找出来时的起点,所以我们很容易想到,这一个过程,相当于已经枚举了实际问题中的起点。
也就是,我们在取ans的最大值时的最小值位置,就可以当实际问题中的起点。
#include<iostream>
#include<algorithm>
#include<vector>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<ctime>
#define fuck(x) cout<<#x<<" = "<<x<<endl;
#define debug(a,i) cout<<#a<<"["<<i<<"] = "<<a[i]<<endl;
#define ls (t<<1)
#define rs ((t<<1)+1)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = ;
const int maxm = ;
const int inf = 2.1e9;
const ll Inf = ;
const int mod = ;
const double eps = 1e-;
const double pi = acos(-);
ll num[maxn];
vector<ll>vec;
bool vis[maxn];
ll sum[maxn];
ll n,s,m,k;
int len;
struct node
{
ll x;
int id;
};
deque<node>q;
ll solve(int p){
q.clear();
for(int i=;i<len;i++){
vec.push_back(vec[i]);
}
for(int i=;i<len;i++){
vec.push_back(vec[i]);
}
ll ans=;
sum[]=vec[];
for(int i=;i<len*;i++){
sum[i]=sum[i-]+vec[i];
}
for(int i=;i<len*;i++){
while(!q.empty()&&q.back().x>sum[i]){
q.pop_back();
}
if(!q.empty()&&q.front().id<i-p){q.pop_front();}
q.push_back(node{sum[i],i});
ans=max(ans,1ll*sum[i]-q.front().x);
}
return ans;
} int main()
{
int T;
scanf("%d",&T);
int cases=;
while(T--){
ll ans=;
cases++;
scanf("%lld%lld%lld%lld",&n,&s,&m,&k);
for(int i=;i<=n;i++){
scanf("%lld",&num[i]);
}
memset(vis,,sizeof(vis));
for(int i=;i<=n;i++){
vec.clear();
if(vis[i]){continue;}
int pos=i;
for(int j=;j<=m;j++){
vec.push_back(num[pos]);
vis[pos]=true;
pos+=k;
if(pos>n){pos%=n;}
if(vis[pos]){break;}
}
len=vec.size();
ll sum=;
for(int i=;i<len;i++){
sum+=vec[i];
}
if(sum<){
ans=max(ans,solve(len));
}
else{
ans=max(ans,solve(m-(m/len-)*len)+(m/len-)*sum);
}
}
printf("Case #%d: %lld\n",cases,max(0ll,s-ans));
}
return ;
}
HDU 6444 Neko's loop(单调队列)的更多相关文章
- hdu 6444 Neko's loop 单调队列优化DP
Neko's loop Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total ...
- HDU - 6444 Neko's loop(循环节+最大子段和)
http://acm.hdu.edu.cn/showproblem.php?pid=6444 题意 一个有n个数的环,每次循环走k步,走到每个点都有具体的权值,问在任意点出发最多走m步的情况下,一开始 ...
- HDU 6444 Neko's loop ( 2018 CCPC 网络赛 && 裴蜀定理 && 线段树 )
题目链接 题意 : 给出一个 n 个元素的环.可以任意选择起点.选完起点后.可以行走 m 步.每次前进 k 个单位.所走到的点将产生正或负贡献.问你一开始得准备多少才能使得初始资金加上在环上获取最大利 ...
- hdu 5945 Fxx and game(单调队列优化DP)
题目链接:hdu 5945 Fxx and game 题意: 让你从x走到1的位置,问你最小的步数,给你两种走的方式,1.如果k整除x,那么你可以从x走一步到k.2.你可以从x走到j,j+t<= ...
- hdu 3410 Passing the Message(单调队列)
题目链接:hdu 3410 Passing the Message 题意: 说那么多,其实就是对于每个a[i],让你找他的从左边(右边)开始找a[j]<a[i]并且a[j]=max(a[j])( ...
- hdu 6319 逆序建单调队列
题目传送门//res tp hdu 维护递增单调队列 根据数据范围推测应为O(n)的. 我们需要维护一个区间的信息,区间内信息是"有序"的,同时需要在O(1)的时间进行相邻区间的信 ...
- HDU - 5289 Assignment (RMQ+二分)(单调队列)
题目链接: Assignment 题意: 给出一个数列,问其中存在多少连续子序列,使得子序列的最大值-最小值<k. 题解: RMQ先处理出每个区间的最大值和最小值(复杂度为:n×logn),相 ...
- HDU 2490 Parade(DPの单调队列)(2008 Asia Regional Beijing)
Description Panagola, The Lord of city F likes to parade very much. He always inspects his city in h ...
- HDU - 5289:Assignment(单调队列||二分+RMQ||二分+线段树)
Tom owns a company and he is the boss. There are n staffs which are numbered from 1 to n in this com ...
随机推荐
- Effective C++: 06继承与面向对象设计
32:确定你的public继承塑模出is-a关系 以C++进行面向对象编程,最重要的一个规则是:public继承表示的是"is-a"(是一种)的关系. 如果令class D以pub ...
- C#总结 标签: c# 2014-12-07 19:07 1148人阅读 评论(47) 收藏
之前考二级的时候,C++没有好好的学,如今到了学C#的时候,又重新明白了一遍出来混,迟早要还得道理,我觉得,其实C#比C++简单,应该是因为之前没有好好学得原因,其实现在学C#,也是和一年前一样,照着 ...
- qt .pro文件和cmakelists.txt配置第三方库
.pro文件引用第三方库文件和头文件路径 1.库文件(LIBS添加的是共享库文件,-L添加目录,-l指定共享库名称) LIBS += -L/usr/local/lib -lmath LIBS的使用就是 ...
- C# —— 枚举
一.使用枚举的优点 枚举能够使代码更加的清晰,它允许使用描述性的名称表示整数值. 枚举使代码更易于维护,有助于确保给变量指定合法的.期望的值. 枚举使代码更易输入. 二.枚举说明 1.简单枚举 枚举使 ...
- iOS UIWebView URL拦截
http://www.cocoachina.com/ios/20150626/12161.html 本文译者:candeladiao,原文:URL filtering for UIWebView on ...
- MaxCompute Studio使用心得系列7——作业对比
在数据开发过程中,我们通常需要将两个作业进行对比从而定位作业运行性能或者结果有差异的问题,但是对比作业时需要同时打开两个studio 的tab页,或者两个Logview页,不停切换进行对比,使用起来非 ...
- 怎么清除火狐浏览器的cookie?
火狐浏览器清除Cookie方法/步骤 1.打开火狐浏览器.并在火狐浏览器工具栏找到并单击“工具”下的“选项”. 2.在打开的“火狐浏览器选项”程序窗口中,找到工具栏中的“隐私”并单击,在隐私选项下找到 ...
- python实用工具包
文本处理 FlashText 大规模关键字搜索利器,据说多余500个关键字时性能会明显优于正则表达式,暂未评测! 调试利器 pysnooper 不需要使用print进行调试
- 使用国内阿里maven私服方法
方法1,在maven的config下setings.xml文件中加入以下代码 <mirrors> <mirror> <id>mirrorId</id> ...
- SuperSocket命令和命令加载器
关键字: 命令, 命令加载器, 多命令程序集 命令 (Command) SuperSocket 中的命令设计出来是为了处理来自客户端的请求的, 它在业务逻辑处理之中起到了很重要的作用. 命令类必须实现 ...