【luoguP4343】自动刷题机

题目

题目背景

曾经发明了信号增幅仪的发明家 SHTSC 又公开了他的新发明:自动刷题机——一种可以自动 AC 题目的神秘装置。

题目描述

自动刷题机刷题的方式非常简单:首先会瞬间得出题目的正确做法,然后开始写程序。每秒,自动刷题机的代码生成模块会有两种可能的结果:

1.写了 x 行代码
2.心情不好,删掉了之前写的 y 行代码。(如果 y 大于当前代码长度则相当于全部删除。)

对于一个 OJ,存在某个固定的正整数长度 n,一旦自动刷题机在某秒结束时积累了大于等于 n 行的代码,它就会自动提交并 AC 此题,然后新建一个文件(即弃置之前的所有代码)并开始写下一题。SHTSC 在某个 OJ 上跑了一天的自动刷题机,得到了很多条关于写代码的日志信息。他突然发现自己没有记录这个 OJ 的 \(n\) 究竟是多少。所幸他通过自己在 OJ 上的 Rank 知道了自动刷题机一共切了 \(k\) 道题,希望你计算 \(n\) 可能的最小值和最大值。

输入格式

第一行两个整数 \(l,k\),表示刷题机的日志一共有 \(l\) 行,一共了切了 \(k\) 题。

接下来 \(l\) 行,每行一个整数 \(x_i\)​,依次表示每条日志。若 \(x_i\)≥0,则表示写了 \(x_i\)行代码,若 \(x_i\)<0,则表示删除了 -\(x_i\)行代码。

输出格式

输出一行两个整数,分别表示 \(n\) 可能的最小值和最大值。
如果这样的\(n\)不存在,请输出一行一个整数 \(−1\)

数据范围

对于 20% 的数据,保证 \(l≤10\)

对于 40% 的数据,保证 \(l≤100\)

对于 60% 的数据,保证 \(l≤2×10^3\)

对于 100% 的数据,保证 $1≤l≤\(10^5\)

链接:

https://www.luogu.com.cn/problem/P4343

思路

初看想法

第一眼看到这个题目的数据范围,显然不是用暴力求解,先试试20%数据

20%数据

20%数据显然可以通过枚举n嘛,把n枚举出来再看看能否切掉k道题目就可以了。等等……枚举n?

100%数据

既然要枚举n,那完全可以用二分来枚举。这不就是一题二分答案嘛,只不过要求一个最大值一个最小值,两次二分就能解决了。

code:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll n,k;
ll a[100000+10];
ll pd(ll x){
    ll sum=0,t=0;
    for(int i=1;i<=n;i++){
        sum+=a[i];
        if(sum<0) sum=0;
        if(sum>=x) t++,sum=0;
    }
    return t;
}
int main(){
    cin>>n>>k;
    for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
    ll left=1,right=1e14;
    ll minans=-1,maxans=-1;
    while(left<=right){
        ll mid=(left+right)/2;
        ll d=pd(mid);
        if(d==k) minans=mid,right=mid-1;
        else if(d<k) right=mid-1;
        else left=mid+1;
    }
    left=1,right=1e14;
    while(left<=right){
        ll mid=(left+right)/2;
        ll d=pd(mid);
        if(d==k) maxans=mid,left=mid+1;
        else if(d<k) right=mid-1;
        else left=mid+1;
    }
    if(minans==-1&&maxans==-1) cout<<-1;
    else
    cout<<minans<<' '<<maxans;
}
posted @ 2020-09-19 18:28  DLS童真  阅读(298)  评论(0)    收藏  举报