题目传送门(内部题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. Hive-java.lang.ClassNotFoundException: org.apache.hadoop.hive.contrib.serde2.MultiDelimitSerDe

    Task with the most failures(): ----- Task ID: task_1555476136794_8201_m_000000 URL: http://hadoop1:8 ...

  2. 大数据平台CentOS7+CDH5.12.1集群搭建

    1.CM(Cloudera Manager)介绍 1.1 简介 Cloudera Manager是一个拥有集群自动化安装.中心化管理.集群监控.报警功能的一个工具,使得安装集群从几天的时间缩短在几个小 ...

  3. python学习-第四天补充-面向对象

    python学习-第四天补充-面向对象 python 私有 --name mangling(名字修改.名字) 在命名时,通过使用两个下划线作为开头,可以使得这个变量或者函数编程私有的,但是这个其实的p ...

  4. 小白如何入门 Python 爬虫?

    本文针对初学者,我会用最简单的案例告诉你如何入门python爬虫! 想要入门Python 爬虫首先需要解决四个问题 熟悉python编程 了解HTML 了解网络爬虫的基本原理 学习使用python爬虫 ...

  5. 搜索专题: HDU1428漫步校园

    漫步校园 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submi ...

  6. 异步IO\数据库\队列\缓存\RabbitMQ队列

    本节内容 Gevent协程 Select\Poll\Epoll异步IO与事件驱动 Python连接Mysql数据库操作 RabbitMQ队列 Redis\Memcached缓存 Paramiko SS ...

  7. reactV16理解

    在 V16 版本中引入了 Fiber 机制.这个机制一定程度上的影响了部分生命周期的调用,并且也引入了新的 2 个 API 来解决问题. 在之前的版本中,如果你拥有一个很复杂的复合组件,然后改动了最上 ...

  8. Python 计算Numpy向量之间的欧氏距离

    vector1 = np.array([1,2,3]) vector2 = np.array([4,5,6]) dist = numpy.sqrt(numpy.sum(numpy.square(vec ...

  9. C++函数声明与定义

    一个C++函数,如果没有函数声明而只有函数定义,程序照样运行,但要求这个函数定义必须放在main函数之前,否则编译按照从上到下的顺序扫描下来,就会出现编译器不认识它的情况. 如果一个程序同时有函数声明 ...

  10. STM32程序加载与调试

    1.STM32程序的ISP下载,只能使用串口1,其它串口不可以.