题目传送门(内部题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. C语言I-博客作业04

    这个作业属于那个课程 C语言程序设计II 这个作业要求在哪里 C语言I博客作业04 我在这个课程的目标是 掌握使用for循环语句实现指定次数的循环程序设计 这个作业在那个具体方面帮助我实现目标 在编写 ...

  2. [转帖]APT34攻击全本分析

    APT34攻击全本分析 https://zhuanlan.kanxue.com/article-8401.htm 高手太多 我等菜鸟目不暇接.. 一.事件综述 2019年4月18日,黑客/黑客组织使用 ...

  3. 基于bs4库的HTML标签遍历方法

    基于bs4库的HTML标签遍历方法 import requests r=requests.get('http://python123.io/ws/demo.html') demo=r.text HTM ...

  4. 画一个心送给心爱的小姐姐,Python绘图库Turtle

    Python绘图库Turtle Turtle介绍 Turtle是Python内嵌的绘制线.圆以及其他形状(包括文本)的图形模块. 一个Turtle实际上是一个对象,在导入Turtle模块时,就创建了对 ...

  5. 思维体操: HDU1287破译密码

    破译密码 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submi ...

  6. Springboot+CAS单点登录

    一:安装CAS 下载cas:https://github.com/apereo/cas 1.1 将cas并打成war包.放入一个干净的tomcat中,启动tomcat测试: http://localh ...

  7. Kali Linux安装及中文指南

    Kali Linux安装及中文指南 Kali Linux安装教程:https://blog.csdn.net/u012318074/article/details/71601382 Kali Linu ...

  8. background的水平条纹和斜向条纹

    水平条纹: <div id="div1"> </div> linear-gradient属性 #div1{ width: 100px; height: 10 ...

  9. Apache Allow 命令

    用于设置哪些客户端可以访问 Apache,格式如下: Allow from [All /全域名/部分域名/IP 地址/网络地址/CIDR 地址] All:表示全部客户端 全域名:表示域名对应的客户端, ...

  10. RMQ 区间最大值最小值 最频繁次数

    区间的最大值和最小值 #include <cstdio> #include <cstring> #include <cmath> #include <iost ...