题目传送门

  传送门I

  传送门II

  传送门III

题目大意

  求一个满足$d\sum_{i = 1}^{n} \left \lceil \frac{a_i}{d} \right \rceil - \sum_{i = 1}^{n} a_{i} \leqslant K$的最大正整数$d$。

  整理一下可以得到条件是$d\sum_{i = 1}^{n} \left \lceil \frac{a_i}{d} \right \rceil \leqslant K + \sum_{i = 1}^{n} a_{i}$

  有注意到$\left \lceil \frac{a_i}{d} \right \rceil$的取值个数不会超过$2\left \lceil \sqrt{a_i} \right \rceil$。

  证明考虑对于$1 \leqslant d \leqslant \left \lceil \sqrt{a_i} \right \rceil$,至多根号种取值,当$d >\left \lceil \sqrt{a_i} \right \rceil$的时候,取值至多为$1, 2, \cdots, \left \lceil \sqrt{a_i} \right \rceil$,所以总共不会超过$2\left \lceil \sqrt{a_i} \right \rceil$个取值。

  所以我们把所有$\left \lceil \frac{a_i}{d} \right \rceil$的取值当成一个点,安插在数轴上,排个序,就愉快地找到了所有分段了。因为每一段内的$d$都是等价的,所以只需要用每一段的左端点计算和,然后判断$\left \lfloor \frac{K + \sum_{i = 1}^{n} a_{i}}{\sum_{i = 1}^{n} \left \lceil \frac{a_i}{d} \right \rceil} \right \rfloor$是否在区间内,如果是就用它去更新答案。

Code

 /**
* Codeforces
* Problem#831F
* Accepted
* Time:997ms
* Memory:100400k
*/
#include <iostream>
#include <cstdio>
#include <ctime>
#include <cmath>
#include <cctype>
#include <cstring>
#include <cstdlib>
#include <fstream>
#include <sstream>
#include <algorithm>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <vector>
#include <stack>
#ifndef WIN32
#define Auto "%lld"
#else
#define Auto "%I64d"
#endif
using namespace std;
typedef bool boolean;
const signed int inf = (signed)((1u << ) - );
const signed long long llf = (signed long long)((1ull << ) - );
const double eps = 1e-;
const int binary_limit = ;
#define smin(a, b) a = min(a, b)
#define smax(a, b) a = max(a, b)
#define max3(a, b, c) max(a, max(b, c))
#define min3(a, b, c) min(a, min(b, c))
template<typename T>
inline boolean readInteger(T& u){
char x;
int aFlag = ;
while(!isdigit((x = getchar())) && x != '-' && x != -);
if(x == -) {
ungetc(x, stdin);
return false;
}
if(x == '-'){
x = getchar();
aFlag = -;
}
for(u = x - ''; isdigit((x = getchar())); u = (u << ) + (u << ) + x - '');
ungetc(x, stdin);
u *= aFlag;
return true;
} #define LL long long int n;
LL C;
int* a;
vector<LL> seg; template<typename T>
T ceil(T a, T b) {
return (a + b - ) / b;
} inline void init() {
readInteger(n);
readInteger(C);
seg.push_back();
a = new int[(n + )];
for(int i = , x; i <= n; i++) {
readInteger(a[i]);
for(int j = ; j * j <= a[i]; j++)
seg.push_back(j), seg.push_back(ceil(a[i], j));
C += a[i];
}
seg.push_back(llf);
} LL res = ;
inline void solve() {
sort(seg.begin(), seg.end());
int m = unique(seg.begin(), seg.end()) - seg.begin() - ;
for(int i = ; i < m; i++) {
LL l = seg[i], r = seg[i + ], temp = ;
for(int i = ; i <= n; i++)
temp += ceil((LL)a[i], l);
LL d = C / temp;
if(d >= l && d < r && d > res)
res = d;
}
printf(Auto"\n", res);
} int main() {
init();
solve();
return ;
}

Brute force

  然后我们来讲点神仙做法。 orz orz orz.....

  不妨设$C = K + \sum_{i = 1}^{n} a_{i}$

  因为所有$\left \lceil \frac{a_i}{d} \right \rceil \geqslant 1$,所以$d\leqslant \left \lfloor \frac{C}{n} \right \rfloor$

  设$d_0 =  \left \lfloor \frac{C}{n} \right \rfloor$。

  假装已经顺利地求出了$d_0, d_1, d_2, \cdots, d_k$,我们找到最大的$d_{k + 1}$满足:

$d_{k + 1}\sum_{i = 1}^{n} \left \lceil \frac{a_i}{d_k} \right \rceil \leqslant  C$

  当$d_{k + 1} = d_k$的时候我们就找到最优解了。

  感觉很玄学?那我来证明一下。

定理1 $d_{k + 1} \leqslant d_{k}$

  证明

  • 当$k = 0$的时候,因为$\sum_{i = 1}^{n} \left \lceil \frac{a_i}{d_0} \right \rceil \geqslant n$,所以$d_{1} = \left \lfloor \frac{C}{\sum_{i = 1}^{n} \left \lceil \frac{a_i}{d_0} \right \rceil} \right \rfloor \leqslant \left \lfloor\frac{C}{n}\right \rfloor = d_0$。
  • 当$k > 0$的时候,假设当$k = m - 1, (m \geqslant 0)$时成立,考虑当$k = m$的时候,由$d_{k} \leqslant d_{k - 1}$可得$\sum_{i = 1}^{n} \left \lceil \frac{a_i}{d_{k - 1}} \right \rceil \leqslant \sum_{i = 1}^{n} \left \lceil \frac{a_i}{d_{k}} \right \rceil $,然后可得$d_{k + 1} \leqslant d_k$。

定理2 当$d_{k + 1} = d_{k}$,$d_k$是最优解

  证明 假设存在$d > d_k$满足条件

  • 显然$d \leqslant d_0$。(不然直接不合法)
  • 显然$d \neq d_j\ \  (0 \leqslant j < k)$。
  • 假设$d_{j} < d < d_{j - 1}\ \ (0 < j \leqslant k)$,那么$C \geqslant d\sum_{i = 1}^{n} \left \lceil \frac{a_i}{d} \right \rceil \geqslant d\sum_{i = 1}^{n} \left \lceil \frac{a_i}{d_{j}} \right \rceil $
    由迭代做法可知$d\leqslant d_{j + 1}\leqslant d_j$,矛盾。

  显然$d = d_k$时是合法的,所以$d_k$是最优解。

  时间复杂度感觉很低,但是我只会证它不超过$O(n\sqrt{\frac{C}{n}})$

Code

 /**
* Codeforces
* Problem#831F
* Accepted
* Time: 31ms
* Memory: 0k
*/
#include <iostream>
#include <cassert>
#include <cstdlib>
#include <cstdio>
#include <vector>
#include <queue>
#ifndef WIN32
#define Auto "%lld"
#else
#define Auto "%I64d"
#endif
using namespace std;
typedef bool boolean; #define ll long long const int N = ; int n;
ll C;
int ar[N]; inline void init() {
scanf("%d"Auto, &n, &C);
for (int i = ; i < n; i++)
scanf("%d", ar + i), C += ar[i];
} ll ceil(ll a, ll b) {
return (a + b - ) / b;
} inline void solve() {
ll dcur = C / n, dans;
do {
swap(dcur, dans), dcur = ;
for (int i = ; i < n; i++)
dcur += ceil(ar[i], dans);
dcur = C / dcur;
} while (dcur != dans);
printf(Auto"\n", dans);
} int main() {
init();
solve();
return ;
}

更新日志

  • 2018-1-28 补上jmr的做法
  • 2018-10-22 给出证明

Codeforces Round #424 (Div. 2, rated, based on VK Cup Finals) Problem F (Codeforces 831F) - 数论 - 暴力的更多相关文章

  1. Codeforces Round #424 (Div. 2, rated, based on VK Cup Finals) Problem C (Codeforces 831C) - 暴力 - 二分法

    Polycarp watched TV-show where k jury members one by one rated a participant by adding him a certain ...

  2. Codeforces Round #424 (Div. 2, rated, based on VK Cup Finals) Problem D (Codeforces 831D) - 贪心 - 二分答案 - 动态规划

    There are n people and k keys on a straight line. Every person wants to get to the office which is l ...

  3. Codeforces Round #424 (Div. 2, rated, based on VK Cup Finals) Problem E (Codeforces 831E) - 线段树 - 树状数组

    Vasily has a deck of cards consisting of n cards. There is an integer on each of the cards, this int ...

  4. Codeforces Round #423 (Div. 2, rated, based on VK Cup Finals) Problem E (Codeforces 828E) - 分块

    Everyone knows that DNA strands consist of nucleotides. There are four types of nucleotides: "A ...

  5. Codeforces Round #424 (Div. 2, rated, based on VK Cup Finals) Problem A - B

    Array of integers is unimodal, if: it is strictly increasing in the beginning; after that it is cons ...

  6. Codeforces Round #423 (Div. 2, rated, based on VK Cup Finals) Problem D (Codeforces 828D) - 贪心

    Arkady needs your help again! This time he decided to build his own high-speed Internet exchange poi ...

  7. Codeforces Round #423 (Div. 2, rated, based on VK Cup Finals) Problem C (Codeforces 828C) - 链表 - 并查集

    Ivan had string s consisting of small English letters. However, his friend Julia decided to make fun ...

  8. Codeforces Round #424 (Div. 2, rated, based on VK Cup Finals)

    http://codeforces.com/contest/831 A. Unimodal Array time limit per test 1 second memory limit per te ...

  9. Codeforces Round #424 (Div. 2, rated, based on VK Cup Finals)A,B,C

    A:链接:http://codeforces.com/contest/831/problem/A 解题思路: 从前往后分别统计递增,相等,递减序列的长度,如果最后长度和原序列长度相等那么就输出yes: ...

随机推荐

  1. webpack使用六

    插件(Plugins) 插件(Plugins)是用来拓展Webpack功能的,它们会在整个构建过程中生效,执行相关的任务. Loaders和Plugins常常被弄混,但是他们其实是完全不同的东西,可以 ...

  2. sqli-labs(十四)(宽字节注入)

    数据库使用gbk编码的时候,会将两个字符合并成一个中文. 写在前面吧,对php的代码审计也会有帮助 直接使用 set character_set_client=gbk 或者是常见的mysql_quer ...

  3. python ---多进程 Multiprocessing

    和 threading 的比较 多进程 Multiprocessing 和多线程 threading 类似, 他们都是在 python 中用来并行运算的. 不过既然有了 threading, 为什么 ...

  4. 步进电机 28BYJ-48介绍和驱动及编程

    28BYJ-48步进电机: 步进电机是一种将电脉冲转化为角位移的执行机构.通俗一点讲:当步进驱动器接收到一个脉冲信号,它就驱动步进电机按设定的方向转动一个固定的角度(及步进角).您可以通过控制脉冲个来 ...

  5. ArrayList 底层实现原理

    ArrayList的底层实现原理 1, 属性:private static final int DEFAULT_CAPACITY = 10; private static final Object [ ...

  6. array_contains 分析函数使用演示

    Hive中的array_contains函数与SQL中的 in关键字 操作类似,用于判定 包含(array_contains)或不包含(!array_contains)关系.与 in不同的是array ...

  7. flask 对URL进行安全验证

    对URL进行安全验证 虽然我们已经实现了重定向会上一个页面的功能,但是安全问题不容忽视,鉴于referer和next容易被串篡改的特性,我们需要对这些值进行验证,否则会形成开放重定向漏洞   以URL ...

  8. 2017-2018-2 20165215 实验四《Android开发基础》实验报告

    2017-2018-2 20165215 实验四<Android开发基础>实验报告 一.实验报告封面 课程:Java程序设计 班级:1652班 姓名:张家佳 学号:20165215 指导教 ...

  9. Linux基础命令---arp

    arp arp指令用来管理系统的arp缓冲区,可以显示.删除.添加静态mac地址.ARP以各种方式操纵内核的ARP缓存.主要选项是清除地址映射项并手动设置.为了调试目的,ARP程序还允许对ARP缓存进 ...

  10. 环绕声5.1ch

    简单说5.1ch就是数字影院中的音频输出术语,环绕立体声输出,让人有置身电影院的感觉,由五个音箱(两个主音箱.两个环绕箱.一个中置箱)+一个低音炮组成 5.1环绕声包括了5个全频带声道和 1个低频效果 ...