题意: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. 学习笔记<3>View接触

    一.View基本概念 1.界面上显示所有的控件都是用对象表示的,即有类,这些类都是View的子类. 2.View的种类 二.在Activity当中获取代表View的对象 1.根据ID可以用方法获取到对 ...

  2. github常见错误提示之一

    如果输入$ Git remote add origin git@github.com:Jomsou(github帐号名)/gitdemo(项目名).git 提示出错信息:fatal: remote o ...

  3. IFrame session(转)

    问题场景: 在一个应用(集团门户)的某个page中, 通过IFrame的方式嵌入另一个应用(集团实时监管系统)的某个页面. 当两个应用的domain 不一样时, 在被嵌入的页面中Session失效.( ...

  4. HashMap的底层实现原理

    HashMap的底层实现原理1,属性static final int MAX_CAPACITY = 1 << 30;//1073741824(十进制)0100000000000000000 ...

  5. spring 源码导入eclipse

    使用 gradle: ..opensource\v3.: 错误: 程序包org.apache.commons.pool.impl不存在 最后发现是依赖的包commons-pool没有配置.关键是刚用 ...

  6. django中orm的批量操作

    ORM批量操作 数据模型定义 from django.db import models class Product(models.Model): name = models.CharField(max ...

  7. MongoDB遇到的疑似数据丢失的问题。不要用InsertMany!

    最近做数据备份的时候发现了有个很严重的问题,那就是数据丢失(最后证明没丢,是别的问题造成的). 问题如下: 我通过两种方式在两个mongoDB集群中,对一组collection进行备份,最后2个备份数 ...

  8. AtCoder Beginner Contest 084(AB)

    A - New Year 题目链接:https://abc084.contest.atcoder.jp/tasks/abc084_a Time limit : 2sec / Memory limit  ...

  9. Java学习路线:Java中的位移运算符介绍

    学习java本来就是一件日积月累的事情,或许你通过自学能掌握一些皮毛技术,学到java的一些基本大面,但想要做到精通,还是需要自己技术的日积月累和工作经验的不断积累. 今天给大家分享的技术知识是:ja ...

  10. 怎样从外网访问内网Jetty?

    本地安装了一个Jetty,只能在局域网内访问,怎样从外网也能访问到本地的Jetty呢?本文将介绍具体的实现步骤. 准备工作 安装并启动Jetty 默认安装的Jetty端口是8080. 实现步骤 下载并 ...