题意:n个数,有一个起始值,按顺序从第一个开始不断循环取数,如果取完后相加小于0就变为0,最多取p个数,问你得到大于等于值g所需要的最小起始值为多少

思路:这题目爆long long爆的毫无准备,到处都有可能爆值。

显然,我们能想出,初始值越大,那么走相同步数所得到的数字就会越大(或相等),那么我们就可以用二分法每次判断是否能得到g值,大概logG * n * C的复杂度。那么现在问题就是怎么判定初始值s是否能得到g值。

我们可以求循环两次的结果差dis = tot2 - tot1,来判断每次循环的走向是增还是减或者不变。之所以算两次循环是因为可能遇到这样的样例:

4 5 10

1 2 -100 20

假设我初始值为10,那么第一次循环后得到20,那么其实不是一次循环就会增长10,因为第二次循环后还是20,所以要循环两次判断走势。

p <= 2n 或者 dis <= 0直接遍历两次循环就行了; p > 2n时,我们就让他一直循环,然后遍历最后一圈+ mod(就是p % n)。为什么不是只遍历最后的mod,而是要提前一圈遍历?因为有可能我在最后一圈里可能遇到在最后几个数中出现了-INF的超小值,我吃了这个超小值之后就不划算了。

最后注意别随时有可能爆long long...orz

代码:

#include<set>
#include<map>
#include<cmath>
#include<queue>
#include<string>
#include<cstdio>
#include<cstring>
#include<sstream>
#include<algorithm>
typedef long long ll;
using namespace std;
const int maxn = 1e5 + ;
const int MOD = 1e9 + ;
const int INF = 0x3f3f3f3f;
ll v[maxn];
ll n, g, p;
bool getMax(ll st){
if(st >= g) return true;
if(p <= n){
ll tot = st;
for(ll i = ; i < p; i++){
tot += v[i];
if(tot < ) tot = ;
if(tot >= g) return true;
}
return false;
}
else{ //p > n
ll tot = st;
for(ll i = ; i < n; i++){
tot += v[i];
if(tot < ) tot = ;
if(tot >= g) return true;
}
ll last = tot;
if(p <= * n){
for(ll i = ; i < p - n; i++){
tot += v[i];
if(tot < ) tot = ;
if(tot >= g) return true;
}
return false;
}
else{ //p > 2n
for(ll i = ; i < n; i++){
tot += v[i];
if(tot < ) tot = ;
if(tot >= g) return true;
}
ll dis = tot - last;
if(dis <= ) return false;
else{
ll k = p / n, rest;
k--;
if(k >= g / dis) return true; //防止爆long long
rest = p - k * n;
tot = last + dis * (k - 1LL);
if(tot >= g) return true;
for(ll i = ; i < n; i++){
tot += v[i];
if(tot < ) tot = ;
if(tot >= g) return true;
}
rest -= n;
for(ll i = ; i < rest; i++){
tot += v[i];
if(tot < ) tot = ;
if(tot >= g) return true;
}
return false;
}
}
}
}
int main(){
int t, ca = ;
scanf("%d", &t);
while(t--){
scanf("%lld%lld%lld", &n, &g, &p);
for(ll i = ; i < n; i++){
scanf("%lld", &v[i]);
}
ll l = , r = g, ans = g;
while(l <= r){
ll m = (l + r) / ;
if(getMax(m)){
r = m - ;
ans = m;
}
else{
l = m + ;
}
}
printf("Case #%d: %lld\n", ca++, ans);
}
return ;
}

UVALive 7501 Business Cycle(二分)题解的更多相关文章

  1. UVALive 7501 Business Cycle

    细心题 #include<bits/stdc++.h> using namespace std; #define rep(i,a,b) for(int i=a;i<=b;++i) # ...

  2. UVALive - 3211 (2-SAT + 二分)

    layout: post title: 训练指南 UVALive - 3211 (2-SAT + 二分) author: "luowentaoaa" catalog: true m ...

  3. UVALive 3971 Assemble(模拟 + 二分)

    UVALive 3971 题意:有b块钱.想要组装一台电脑,给出n个配件的种类,名字,价格,品质因子.若各种类配件各买一个,总价格<=b,求最差品质配件的最大品质因子. 思路: 求最大的最小值一 ...

  4. poj 1064 Cable master 二分 题解《挑战程序设计竞赛》

    地址 http://poj.org/problem?id=1064 题解 二分即可 其实 对于输入与精度计算不是很在行 老是被卡精度 后来学习了一个函数 floor 向负无穷取整 才能ac 代码如下 ...

  5. UVALive 5000 Underwater Snipers --二分

    题意:一条河岸线y=k,y>k区域有n个敌人,现在要在y<=k区域布置S个狙击手,狙击手的狙击范围为距离自己半径为D的圆内,问满足能够狙死所有的敌人的情况下,离河岸线最近的那个狙击手的离河 ...

  6. UVALive 4949 Risk(二分网络流、SAP)

    n个区域,每个区域有我方军队a[i],a[i]==0的区域表示敌方区域,输入邻接矩阵.问经过一次调兵,使得我方边界处(与敌军区域邻接的区域)士兵的最小值最大.输出该最大值.调兵从i->j仅当a[ ...

  7. UVALive 6168 Fat Ninjas --二分小数+搜索

    题意:一个NxN的网格地板,有一些激光束从天花板垂直射向地面的某个网格,一个圆要安全地从左走到右,不碰到上边界,下边界以及激光束,问这个圆的直径最大能达到多大. 分析:可以二分直径,关键在check函 ...

  8. UVALive 6525 Attacking rooks 二分匹配 经典题

    题目链接:option=com_onlinejudge&Itemid=8&page=show_problem&problem=4536">点击打开链接 题意: ...

  9. UVALive 4725 Airport(二分)

    题目链接 题意 机场有两种飞机,每小时一些飞机到达,每小时安排一架飞机起航.求任意时刻中两种飞机数目的最大值的最小值. 分析 首先肯定是二分来做.这里的难点在于如何判断飞机数目是否合法.一开始忽略了某 ...

随机推荐

  1. [13]Windows 内核情景分析 --- 网络通信

    典型的基于tcpip协议套接字方式的网络通信模块层次: 应用程序 socket api WS2_32.dll socket irp Afd.sys tdi irp Tcpip.sys 回调函数接口 各 ...

  2. 32网络通信之Poll模型

    多路复用并发模型  -- poll #include<poll.h> int  poll(struct pollfd *fds,  unsigned int nfds, int timeo ...

  3. 谈谈html中一些比较"偏门"的知识(map&area;iframe;label)

    说明:这里所说的"偏门"只是相对于本人而言,记录在此,加深印象.也希望有需要的朋友能获得些许收获! 1.空元素(void):没有内容的元素. 常见的有:<br>,< ...

  4. Keras 资料

    http://www.360doc.com/content/17/0415/12/1489589_645772879.shtml http://adventuresinmachinelearning. ...

  5. 【Linux学习八】脚本编程

    环境 虚拟机:VMware 10 Linux版本:CentOS-6.5-x86_64 客户端:Xshell4 FTP:Xftp4 一.多层bash#.和source都是当前bash [root@nod ...

  6. Linux 系统管理命令

    1,uanme 查看是什么系统 uname - r 查看系统内核版本 2 cat /proc/cpuinfo 查看cpu 信息 3 cat /proc/meminfo 查看内存信息 4 date 查看 ...

  7. flask 使用Flask-WTF处理表单

    使用Flask-WTF处理表单 扩展Flask-WTF继承了WTFforms,使用它可以在flask中更方便的使用WTForms.Flask-WTF将表单数据解析.CSRF保护.文件上传等功能与Fla ...

  8. webpack系统配置

    简言之,webpack 是一个模块打包器 (module bundler),能够将任何资源如 JavaScript 文件.CSS 文件.图片等打包成一个或少数文件. 为什么要用Webpack? 首先, ...

  9. SQL表分区之一

    一般情况下,我们建立数据库表时,表数据都存放在一个文件里. 但是如果是分区表的话,表数据就会按照你指定的规则分放到不同的文件里,把一个大的数据文件拆分为多个小文件,还可以把这些小文件放在不同的磁盘下由 ...

  10. java-web的mybatis的学习

    idea开发必须是把Mapper文件与配置文件放到Resources标记的classpath目录下,eclips好像放到哪都行指定好路径就可以了, maven里面做好配置resources的路径,不然 ...