zoukankan      html  css  js  c++  java
  • bzoj4590 [Shoi2015]自动刷题机

    Description

    曾经发明了信号增幅仪的发明家SHTSC又公开了他的新发明:自动刷题机--一种可以自动AC题目的神秘装置。自动刷题机刷题的方式非常简单:首先会瞬间得出题目的正确做法,然后开始写程序,每秒,自动刷题机的代码生成模块会有两种可能的结果:
    A.写了x行代码。
    B.心情不好,删掉了之前写的y行代码。(如果y大于当前代码长度则相当于全部删除。)
    对于每个OJ所有题目,存在某个固定的长度n>0。一旦自动刷题机在某秒结束时积累了大于等于n行的代码,它就会自动提交并AC此题,然后新建一个文件开始写下一题。SHTSC在某个OJ上跑了一天的自动刷题机,得到了很多条关于写代码的日志信息。他突然发现自己没有记录这个OJ的n究竟是多少。所幸他通过自己在OJ上的Rank知道了机一共切了k道题。希望你计算n可能的最小值和最大值。 

    Input

    第一行两个整数l,k,表示刷题机的日志一共有l行,一共了切了k题。
    第二行l个整数,x1…xl。xi>=0表示写了xi行代码。xi<0表示删除了这道题的-xi行代码。
    1<=l,k<=100000,|xi|<=10^9

    Output

    输出两个数a,b。分别代表n可能的最小值和最大值。如果不存在这样的n则输出-1。
     

    Sample Input

    4 2
    2
    5
    -3
    9

    Sample Output

    3 7
    //样例1:如果n=2那么刷题机就会切掉3题。但如果n>7刷题机最多只能切1题。考虑n=4发生了什么。
    第一秒:刷题机写了2行。
    第二秒:刷题机又写了5行,共有7行,提交,自信AC。
    第三秒:刷题机删掉了3行,共有0行。
    第四秒:刷题机写了9行,共有9行,提交,自信AC。
    一共AC了两题。

    正解:二分答案。

    显然$n$满足单调性,两次二分答案即可。注意答案的上下界。

     1 //It is made by wfj_2048~
     2 #include <algorithm>
     3 #include <iostream>
     4 #include <cstring>
     5 #include <cstdlib>
     6 #include <cstdio>
     7 #include <vector>
     8 #include <cmath>
     9 #include <queue>
    10 #include <stack>
    11 #include <map>
    12 #include <set>
    13 #define inf (1000000000000000LL)
    14 #define N (200010)
    15 #define il inline
    16 #define RG register
    17 #define ll long long
    18 #define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
    19 
    20 using namespace std;
    21 
    22 ll a[N],n,k,ans1,ans2;
    23 
    24 il ll gi(){
    25     RG ll x=0,q=1; RG char ch=getchar();
    26     while ((ch<'0' || ch>'9') && ch!='-') ch=getchar();
    27     if (ch=='-') q=-1,ch=getchar();
    28     while (ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar();
    29     return q*x;
    30 }
    31 
    32 il ll check(RG ll key){
    33     RG ll sum=0,tot=0;
    34     for (RG ll i=1;i<=n;++i){
    35     sum=max(sum+a[i],0LL);
    36     if (sum>=key) ++tot,sum=0;
    37     }
    38     return tot;
    39 }
    40 
    41 il void findmin(){
    42     RG ll l=1,r=inf,mid;
    43     while (l<=r){
    44     mid=(l+r)>>1;
    45     if (check(mid)<=k) ans1=mid,r=mid-1; else l=mid+1;
    46     }
    47     return;
    48 }
    49 
    50 il void findmax(){
    51     RG ll l=1,r=inf,mid;
    52     while (l<=r){
    53     mid=(l+r)>>1;
    54     if (check(mid)>=k) ans2=mid,l=mid+1; else r=mid-1;
    55     }
    56     return;
    57 }
    58 
    59 il void work(){
    60     n=gi(),k=gi(); for (RG ll i=1;i<=n;++i) a[i]=gi(); findmin(),findmax();
    61     if (check(ans1)!=k || check(ans2)!=k) puts("-1");
    62     else printf("%lld %lld
    ",ans1,ans2); return;
    63 }
    64 
    65 int main(){
    66     File("auto");
    67     work();
    68     return 0;
    69 }
  • 相关阅读:
    动态规划
    平衡二叉树与自平衡二叉树(红黑树)的区别
    算法可视化网站
    字符串查找算法总结(暴力匹配、KMP 算法、Boyer-Moore 算法和 Sunday 算法)
    既然红黑树那么好,为啥hashmap不直接采用红黑树,而是当大于8个的时候才转换红黑树?
    平衡二叉树(AVL树)
    经典的hash函数
    正则表达式之基本原理
    正则表达式只有主语和状语
    模式匹配算法:扫描+特征比较
  • 原文地址:https://www.cnblogs.com/wfj2048/p/7110992.html
Copyright © 2011-2022 走看看