Neko's loop

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)

Total Submission(s): 1386 Accepted Submission(s): 316

Problem Description

Neko has a loop of size n.

The loop has a happy value ai on the i−th(0≤i≤n−1) grid.

Neko likes to jump on the loop.She can start at anywhere. If she stands at i−th grid, she will get ai happy value, and she can spend one unit energy to go to ((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 m unit energies and she wants to achieve at least s happy value.

How much happy value does she need at least before she jumps so that she can get at least s 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.

Input

The first line contains only one integer 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).

The next line contains n integers, the i−th integer is ai−1(−109≤ai−1≤109)

Output

For 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

思路

  • 首先通过观察可以发现从i开始走,每次走到(i+k)%n,总可以走回i,存在循环,因此暴力把每个循环处理出来,每处理出来一个循环就计算一个

    大佬们都用裴蜀定理定理直接知道了不同循环的数量gcd(n,k),还有每个循环的长度n/gcd(n,k)...orz,看了半天并不知道为什么,求教呀
  • 然后就是对每个循环串求最长子段和
    • 首先将前缀和处理出来,线段树维护区间最小值(前缀和),每次求i-m~i-1前缀和的最小值,然后用sum[i]-sum[min]更新答案
    • 依旧将前缀和处理出来,用递增的单调队列,维护前面i-m~i-1之间前缀和的最小值
  • 关于对于循环串的处理

    假设循环串的长度为len,能走m步

    • 考虑m/len(默认作为横跨两段的串)和m%len两段,我们只需要在一个长度为2*len的循环串中,找到长度不超过m%len的最长连续子段即可,然后看看一整串的和是否大于零,若大于0,则加上m/len个sum[len](整串的贡献)即可
    • 若m>len,则有另外一种可能,就是m%len+m/len个整段这种分配方式并不是最优的,原因在于

    假设我们单独取m%len(横跨串)和一整段len来看,可能会存在一个长度大于m%len的横跨串的贡献比m%len+len还大,因此我们可以舍弃一段len,然后使得横跨串的长度从m%len变成len


#include<bits/stdc++.h>
#define ll long long
#define M 10005
using namespace std;
int T,ks,n,tot,m,vi[M],tg[M],len,i,j,k,h,t,Q[M],tp;
ll a[M],s[M<<1],S,ans,re;
int main(){
scanf("%d",&T);
for(ks=1;ks<=T;ks++){
re=-1e16;
memset(vi,0,sizeof(vi));
scanf("%d%lld%d%d",&n,&S,&m,&k);
for(i=0;i<n;i++)scanf("%lld",&a[i]);
for(i=0;i<n;i++){
len=0;
for(j=i;;j=(j+k)%n){
if(!vi[j]){
vi[j]=1;
tg[++len]=j;
}
else break;
}
if(len==0)continue;
for(j=1;j<=2*len;j++){
if(j<=len)s[j]=s[j-1]+a[tg[j]];
else s[j]=s[j-1]+a[tg[j-len]];
}
ans=0;
h=t=0;Q[t++]=0;tp=m;
if(s[len]>=0){ans+=s[len]*(tp/len);tp%=len;}
else tp=min(tp,len);
for(j=1;j<=2*len;j++){
while(h<t&&j-tp>Q[h])h++;
if(h<t)re=max(re,ans+s[j]-s[Q[h]]);
while(h<t&&s[Q[t-1]]>=s[j])t--;
Q[t++]=j;
}
if(m>=len){
tp=m-len;ans=0;
if(s[len]>=0)ans+=s[len]*(tp/len);
tp=len;
h=t=0;Q[t++]=0;
for(j=1;j<=2*len;j++){
while(h<t&&j-tp>Q[h])h++;
if(h<t)re=max(re,ans+s[j]-s[Q[h]]);
while(h<t&&s[Q[t-1]]>=s[j])t--;
Q[t++]=j;
}
}
}
printf("Case #%d: %lld\n",ks,max(0ll,S-re));
}
}

hdu6444 2018中国大学生程序设计竞赛 - 网络选拔赛 1007 Neko's loop的更多相关文章

  1. 2018中国大学生程序设计竞赛 - 网络选拔赛 1001 - Buy and Resell 【优先队列维护最小堆+贪心】

    题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6438 Buy and Resell Time Limit: 2000/1000 MS (Java/O ...

  2. 2018中国大学生程序设计竞赛 - 网络选拔赛 1010 YJJ's Salesman 【离散化+树状数组维护区间最大值】

    题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6447 YJJ's Salesman Time Limit: 4000/2000 MS (Java/O ...

  3. 2018中国大学生程序设计竞赛 - 网络选拔赛 1009 - Tree and Permutation 【dfs+树上两点距离和】

    Tree and Permutation Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Oth ...

  4. HDU - 6440 Dream 2018中国大学生程序设计竞赛 - 网络选拔赛

    给定的\(p\)是素数,要求给定一个加法运算表和乘法运算表,使\((m+n)^p = m^p +n^p(0 \leq m,n < p)\). 因为给定的p是素数,根据费马小定理得 \((m+n) ...

  5. 2018中国大学生程序设计竞赛 - 网络选拔赛 Dream hdu6440 Dream 给出一个(流氓)构造法

    http://acm.hdu.edu.cn/showproblem.php?pid=6440 题意:让你重新定义任意一对数的乘法和加法结果(输出乘法口诀表和加法口诀表),使得m^p+n^p==(m+n ...

  6. 2018中国大学生程序设计竞赛 - 网络选拔赛 Solution

    A - Buy and Resell 题意:给出n个交易点,每次能够选择买或者卖,求获得最大利润 思路:维护两个优先队列,一个是卖,一个是替换,当价格差相同时,优先替换,因为次数要最少 #includ ...

  7. 2018中国大学生程序设计竞赛 - 网络选拔赛 4 - Find Integer 【费马大定理+构造勾股数】

    Find Integer Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Tota ...

  8. 2018中国大学生程序设计竞赛 - 网络选拔赛 hdu 6440 Dream 模拟

    Dream Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Subm ...

  9. 2018中国大学生程序设计竞赛 - 网络选拔赛 hdu6438 Buy and Resell 买入卖出问题 贪心

    Buy and Resell Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)To ...

随机推荐

  1. PTA 7-50 畅通工程之局部最小花费问题(最小生成树Kruskal)

    某地区经过对城镇交通状况的调查,得到现有城镇间快速道路的统计数据,并提出“畅通工程”的目标:使整个地区任何两个城镇间都可以实现快速交通(但不一定有直接的快速道路相连,只要互相间接通过快速路可达即可). ...

  2. bitcode?

    今天在网站上看到一篇关于第三方库不包含bitcode就会报错的文章,感觉剖析得很详细,分享出来,希望可以对iOS初入门者有所帮助.下面我们就一起来看看吧. 用Xcode 7 beta 3在真机(iOS ...

  3. 用java修改文件的编码

    1.将本地的文件转换成另外一种编码输出,主要逻辑代码如下: /** * 将本地文件以哪种编码输出 * @param inputfile 输入文件的路径 * @param outfile 输出文件的路径 ...

  4. PHP系统编程--PHP进程信号处理(转)

    原地址:https://www.cnblogs.com/linzhenjie/p/5485436.html PHP的pcntl扩展提供了信号处理的功能,利用它可以让PHP来接管信号的处理,在开发服务器 ...

  5. YII2中使用控制台命令

    有些时候我们需要通过crontab在后台跑一些定时脚本,这时候就需要用到控制台命令了. 我们在commands目录下创建TestController.php,当然脚本的位置是可以随意指定的,只需要在c ...

  6. bootstrap 折叠collapse失效

    手动点击折叠,然后调用折叠全部以后,在手动点击折叠项,折叠失效. 方法,折叠项是通过添加或删除".in"来实现,实现如下 $(".collapse.in").c ...

  7. Query to find the eligible indexes for rebuilding

    Query to find the eligible indexes for rebuilding The following script can be used to determine whic ...

  8. CSS 图片居中

    } .left-logo a { height: 100px; width: 55px; display: block; } .left-logo a img{ height: ; width: 55 ...

  9. python面向对象的三大特征

    1.封装: 封装就是对类和对象的成员访问进行限制,设定可以访问的方式和不可以访问的方式. 分类: 私有化的封装:当前类/对象种可以使用,类/对象外和子类/对象都不可以用 受保护的封装:当前类/对象和子 ...

  10. Ubuntu12.04(64bit)下安装Qt4总结

    本文主要介绍linux系统Ubuntu12.04(64bit)下Qt4.8.5的安装,其中还涉及Fedora9下Qt4的安装. 1.下载软件:去Qt的官网下载Qt4.8.5和Qt Creator软件, ...