题目传送门(内部题1)


输入格式

第一行两个整数$n$,$k$,代表树苗的数量和最大看书的总长度。
第二行n个整数$a_i$,代表林先森希望每棵树苗的最终高度。


输出格式

一行一个整数,代表最大可能的d值。


样例

样例输入:

3 4

1 3 5

样例输出:

3


数据范围与提示

样例解释:
第$3$天林先森砍掉了第一和第二棵树苗,第$6$天林先森砍掉了第三棵树苗。总共砍树的长度为$(3-1)+(3-3)+(6-5)=3$米。可以证明更大的d值无法满足要求。

数据范围:

对于$20%$的数据,$a_i ≤ {5×10}^5$。

另有$20%$的数据,$k≤1$。

对于所有的数据,$1≤n≤100$,$0≤k≤{10}^{11}$,$1≤a_i≤{10}^9$。


题解

看到$k$很大,$n$很小,优先选择从$n$入手。

$20\%$算法:

暗中观察数据范围,有$20%$的数据$k≤1$,怎么办呢?

这个时候分为两种情况:

  $\alpha.k=0$,那么就是说我们每一次都要赶巧了在这棵树苗长到最终高度那一天砍掉,所以答案即为所有最终高度的最大公约数。

  $\beta,k=1$,因为n比较小,所以我们每次枚举树苗,将它的最终高度+1,然后再求所有树苗的最终高度的最大公约数,取最大值即可。

期望得分:$20$分。

实际得分:$20$分。

$40\%$算法:

开始推式子,设这个天数为$d$,那么砍掉树苗i的高度即为$\left \lceil \frac{a_i}{d} \right \rceil \times d$,那么,可以列出式子:

$\sum \limits_{i=1}^{n} \left \lceil \frac{a_i}{d} \right \rceil \times d - a_i \leqslant k$

移项得:$\sum \limits_{i=1}^{n} \left \lceil \frac{a_i}{d} \right \rceil \times d \leqslant k + \sum \limits_{i=1}^{n} a_i$

惊喜发现上面不等式右边是定值,于是我们设$k + \sum \limits_{i=1}^{n} a_i$为$C$,先让$d=1$,每次让$d++$,当$d \geqslant \min a_i + k$时,不可能在有答案,所以这就是$d$的上界。

期望多得分数:$10$分。

$100\%$算法:

显然,$40\%$时间复杂度还是不允许,但是我们发现,有的d没有必要枚举。

注意对于每个$a_i$,$\left \lceil \frac{a_i}{d} \right \rceil$只有$\sqrt{a_i}$种不同的取值,因此,$\sum \limits_{i=1}^{n}\left \lceil \frac{a_i}{d} \right \rceil$只有$n \times \sqrt{a_i}$种不同的取值,利用数论分块,可以知道下一个d为$\frac{C}{\left \lceil \frac{C}{d+1} \right \rceil}$。

时间复杂度:$O( \sqrt{(\min a_i + k) \times n})$。

期望得分:$100$分。

实际得分:$100$分。


代码时刻

$20\%$算法:

#include<bits/stdc++.h>
using namespace std;
int n,k;
long long a[1000001];
long long ans;
long long gcd(long long x,long long y)
{return y==0?x:gcd(y,x%y);}
int main()
{
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++)
scanf("%lld",&a[i]);
if(!k)//特判k==0
{
ans=a[1];
for(int i=2;i<=n;i++)
ans=gcd(ans,a[i]);
printf("%lld",ans);
}
if(k==1)//特判k==1
{
long long flag=a[2];
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(i!=j)flag=gcd(flag,a[j]);
else flag=gcd(flag,a[j]+1);//将它+1
}
ans=max(ans,flag);
flag=a[1];
}
printf("%lld",ans);
}
return 0;
}

$40\%$算法(记得加上上面代码的那一段):

#include<bits/stdc++.h>
using namespace std;
int n;
long long a[100001];
long long sigma;
long long ans;
int main()
{
scanf("%d%lld",&n,&sigma);
for(int i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
sigma+=a[i];
}
for(long long d=1;d<=sigma;d++)
{
long long flag=0;
for(int i=1;i<=n;i++)
{
if(a[i]%d)flag+=(a[i]/d+1)*d;
else flag+=a[i];
}
if(flag<=sigma)ans=d;
}
printf("%lld",ans);
return 0;
}

$100\%$算法:

#include<bits/stdc++.h>
using namespace std;
int n;
long long k;
long long a[1000001];
long long sigma,maxn;
long long ans;
int main()
{
scanf("%d%lld",&n,&k);
sigma=k;
for(int i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
sigma+=a[i];
maxn=max(maxn,a[i]);
}
maxn+=k;
long long d=1;
while(1)
{
long long flag=0;
for(int i=1;i<=n;i++)
{
if(a[i]%d)flag+=(a[i]/d+1)*d;
else flag+=a[i];
}
if(flag<=sigma)ans=d;
if(maxn<=d)break;//上界
d=sigma/(sigma/(d+1));//更新d
}
cout<<ans<<endl;
return 0;
}

rp++

[CSP-S模拟测试]:砍树(数学+模拟)的更多相关文章

  1. [CSP-S模拟测试]:最大值(数学+线段树)

    题目背景 $Maxtir$最喜欢最大值. 题目传送门(内部题128) 输入格式 第$1$行输入四个正整数$n,m,q$. 第$2$至$n+1$行中,第$i+1$行输入魔法晶石$i$的三种属性$(x_i ...

  2. [CSP-S模拟测试]:Equation(数学+树状数组)

    题目描述 有一棵$n$个点的以$1$为根的树,以及$n$个整数变量$x_i$.树上$i$的父亲是$f_i$,每条边$(i,f_i)$有一个权值$w_i$,表示一个方程$x_i+x_{f_i}=w_i$ ...

  3. [CSP-S模拟测试]:Race(数学+Trie树)

    题目描述 一年一度的运动会开始了.有$N$个选手参赛,第$i$个选手有一个能力值(保证$A[i]$两两不同),比赛一共进行了天.在第$j$天($0\leqslant j\leqslant 2^{m-1 ...

  4. [CSP-S模拟测试]:旅行(数学+线段树)

    题目传送门(内部题12) 输入格式 第一行,一个整数$n$,代表树的点数.第二行,$n$个整数,第$i$个整数是$B_i$,描述排列$B$.接下来$n−1$行,每行两个整数$u,v$,描述一条树边$( ...

  5. noip 2018.10.14 模拟赛 砍树

    数学问题... 根据题意,有: 移项,整理,得: 记 于是 那么 可以看到,最多只会有2*个取值(显而易见) 于是对应的,可能产生效果的d也只会有个,于是我们把他们找出来,扔进一个数组里然后排序,去重 ...

  6. [CSP-S模拟测试]:超级树(DP)

    题目传送门(内部题5) 输入格式 一行两个整数$k$.$mod$,意义见上. 输出格式 一行一个整数,代表答案. 样例 样例输入1: 2 100 样例输出1: 样例输入2: 3 1000 样例输出2: ...

  7. [CSP-S模拟测试]:不等式(数学)

    题目描述 小$z$热衷于数学.今天数学课的内容是解不等式:$L\leqslant S\times x\leqslant R$.小$z$心想这也太简单了,不禁陷入了深深的思考:假如已知$L,R,S,M$ ...

  8. [CSP-S模拟测试]:A(数学)

    题目传送门(内部题44) 输入格式 一行四个整数,分别表示$S,T,a,b$. 输出格式 输出最小步数,数据保证有解. 样例 样例输入: 10 28 4 2 样例输出: 数据范围与提示 样例解释: 先 ...

  9. [CSP-S模拟测试]:装饰(数学)

    题目传送门(内部题147) 输入格式 每个测试点第一行一个正整数$T$,表示该测试点内的数据组数. 接下来$T$行,每行三个非负整数$a,b,c$,含义如题目中所示. 输出格式 对每组数据输出一行一个 ...

随机推荐

  1. 2019JAVA第二次实验报告

    Java实验报告 班级 计算机科学与技术二班 学号 20188442 姓名 吴怡君 完成时间 2019/9/19 评分等级 实验二 Java简单类与对象 实验目的 掌握类的定义,熟悉属性.构造函数.方 ...

  2. 多线程17-Async Programming Model

        );             ThreadId = Thread.CurrentThread.ManagedThreadId;             ;             RunOnT ...

  3. [转帖]SQL 里面的 case when 的用法

    SQL之case when then else end用法介绍 https://www.2cto.com/database/201804/740772.html 要培训了 看到有case when 之 ...

  4. DockerFile与镜像(Image)仓库

    深入Docker 之 Image: 当我们使用docker pull mysql 这个命令获取镜像的时候,到底他是怎么做的?我们登录官方提供的仓库看一下 https://github.com/dock ...

  5. P1177快速排序

    这是一个快速排序的模板题.拿到题后便写了quicksort(确定一个基准数,利用两个哨兵,把大的放右边,小的放左边,再递归实现排序),但是竟然TLE了60pts(???),于是翻看dalao们的题解, ...

  6. PDFObject的使用(转)

    1.pdfobject.js官网:https://pdfobject.com/ 2.在html文件中引入这个文件,以pdfobject.min.js为例 1 <script type=" ...

  7. webpack4+vue打包简单入门

    前言 最近在研究使用webpack的使用,在查阅了数篇文章后,学习了webpack的基础打包流程. 本来就可以一删了之了,但是觉得未免有点可惜,所以就有了这篇文章,供大家参考. webpack打包的教 ...

  8. 6-1 如何读写csv数据

    >>> from urllib import urlretrieve >>> urlretrieve('http://table.finance.yahoo.com ...

  9. vue eslint 规范配置

    vue eslint 规范配置 为了代码格式统一,避免一些低级或者不合理的错误,现强行使用eslint的 standard规范 项目配置 目前都是使用 vue 提供的脚手架进行开发的,虽然 vue-c ...

  10. Pose &&Get的区别

    从一个页面转向另一个页面的请求方式有两种,Post和Get. 如果从原理上来探究他们的区别,涉及到Http传输协议的细节,本文不加探究,只讨论一下表象. 1.Post传输数据时,不需要在URL中显示出 ...