首页 > 其他分享 >一类初等函数下取点问题

一类初等函数下取点问题

时间:2024-07-29 22:40:14浏览次数:12  
标签:直线 一个点 函数 leq 枚举 2M 取点 初等 log

等差数列方向

给 \(N\) 棵树,第 \(i\) 棵树的坐标是 \(a_i \ (-M \leq a_i \leq M)\) 。可以花费 \(b_i\) 的代价将 \(a_i\) 修改为任意整数。询问 \(a_1, a_2, \cdots, a_N\) 构成等差数列需要的最小代价。

思路:
若 \(a_1, a_2, \cdots, a_N\) 是等差数列,则 \((i, a_i)\) 在二维空间上落在一条直线 \(y = A_1 + (d - 1)x = c + kx\) 上,且 \(k = 0 \vee 1 \mid k\) 。

由于 \(f(x) = c x^{0} + k x^{1}\) 是 \(deg\) 为 \(1\) 的多项式,根据插值理论或线性代数理论,可以用两个点确定。

一个经典的 trick 是: 直线经过至少一个点一定比不经过点更优。

  • 如果以两点式处理,则直线经过两个点比经过一个点和经过更多点更优。

  • 或者以点斜式处理,只需枚举一个斜率,且经过一个点。

方向一:

从两点式考虑。

我们可以 \(O(N^{2})\) 枚举两个点,然后计算这两个点对应直线的贡献。

可以借助直线的一般式 \(Ax + By + C = 0\) (一般是需要约分)维护直线,用 \(\{(A, B, C), value\}\) 表示每条直线上点的 \(b_i\) 贡献和。

答案就是 \(\sum b_i - max\{value\}\) ,时间复杂度 \(O(N^{2} \log N^{2})\) 。

方向二:

从点斜式考虑。

重新确定 \(a\) 数组是从 \(0\) 编号的,即 \(a\) 数组为 \(a_0, a_1, a_2, \cdots, a_{N - 1}\) 。这样可以让第一个点在 \(y\) 轴上,方便点斜式的讨论。

我们考虑一条过 \((0, -M)\) 的直线 \(f(x) = -M + kx\) 。

我们可以取直线过另一个点 \((1, M), (2, M), (3, M), \cdots, (N - 1, M), (N - 1, M - 1), (N - 1, M - 2), \cdots, (N - 1, -M)\) ,初步有 \(0 \leq k \leq 2M\) 。

又注意到等差数列构成的直线,斜率要么是 \(0\) ,要么是 \(1\) 的倍数。则 \(k = 0\) 或者 \(1 \leq k \leq 2M\) 。

由于答案直线过 \((0, A)\) 且 \(A \geq -M\) ,则在 \(f(x)\) 下面的所有点一定要改,而可能要改的是严格在 \(f(x)\) 上方的点,不妨称这些点为有效点。

\(k = 0\) 时可以维护键值对 \((y, value)\) ,对所有存在的 \(a_i\) 权值,计算对应的若干点的 \(b_i\) 贡献。时间复杂度 \(O(N \log N)\) 。

所以只需考虑 \(1 \leq k \leq 2M\) 。

不难发现直线 \(f(x)\) 经过点 \((i, -M + ki)\) ,而有效点是一段前缀满足 \(-M + ki \leq M\) 。继而有 \(\forall i, i \leq \lfloor \frac{2M}{k} \rfloor\) 的点为有效点。

\[\sum_{k = 1}^{2M} \lfloor \frac{2M}{k} \rfloor < \sum_{k = 1}^{+\infty} \frac{2M}{k} \leq 2M \ln 2M = O(M \log M) \]

显然有效点的个数为 \(O(M \log M)\) ,同时每个有效点可以根据点斜式确定一条直线。

现在考虑答案直线 \(l = A_0 + k(i - 1)\) ,\(l\) 经过一个点会更优,可以枚举所有有效点作为一个固定点。

假设此时的枚举的斜率是 \(k\) ,枚举的固定有效点是 \(a_i\) ,则 \(A_0 + k(i - 1) = a_i \Rightarrow A_0 = a_i - k(i - 1)\) 。

可以维护键值对 \(\{(A_0, k), value\}\) ,对每个固定点计算它对对应直线的 \(b_i\) 贡献。

获得贡献最大的直线 \(l = A_0 + k(i - 1)\) ,是需要修改贡献最少的直线。

最后我们让这根直线和 \(O(N)\) 跳斜率为 \(0\) 的直线取更优值。

总时间复杂度为 \(O(M \log M)\) 。

等比数列方向

给 \(N\) 棵树,第 \(i\) 棵树的坐标是 \(a_i (0 \leq a_i \leq M)\) 。可以花费 \(b_i\) 的代价将 \(a_i\) 修改为任意非负整数。询问 \(a_1, a_2, \cdots, a_N\) 构成等比数列需要的最小代价。

这里限定为正数是因为非初等函数的处理非常困难。

思路:

若 \(a_1, a_2, \cdots, a_N\) 是等比数列,则 \((i, a_i)\) 在二维空间上落在 \(y = A_1 q^{x - 1}\) 上。

要么 \(q = 1\) ,\(f(x) = A_1 q^{x - 1}\) 是一条直线,可以通过维护 \((y, value)\) 以 \(O(N \log N)\) 算出这种每个权值的获得的点的 \(b_i\) 贡献。

否则 \(q > 0 \wedge q \neq 1\) 。(题目不需要同时讨论 \(q < 0\) 的情况,因为这很困难)

这时 \(f(x) = A_1 q^{x - 1}\) 并不是一个多项式,不能通过若干个点确定。

但至少是一个通过常函数 \(c\) 乘以指数函数 \(a^{x} \ (a \neq 1 \wedge a > 0)\) 得到的初等函数,是一条简单曲线,依旧具有简单的性质。

这个初等函数首先可以通过一个公比 \(q(q > 0)\) 和一个点 \((1, A_1)\) 确定。

根据经典 trick , \(f(x) = A_1 q^{x - 1}\) 至少经过一个点最优。

如果曲线真的只经过了一个点,不妨 \(O(N)\) 处理出 \(\sum_{i = 1}^{N} b_i - b_k\) 。

于是接下来考虑经过至少两个点的曲线,这样会使得曲线的样本空间更小,\(q\) 的取值范围也更小。

我们可以 \(O(N)\) 枚举一个点 \((i, a_i)\) 作为定点,然后枚举 \(q\) ,需要保证 \(q^{i - 1} \mid a_i\) 。于是可以计算出 \(A_1 = \frac{a_i}{q^{i - 1}}\) 。

若 \(\forall i \geq 2, a_i < A_1 q^{i - 1}\) ,则这些曲线依旧是只会经过 \((i, a_i)\) 这一个点。这种情况已经被计算过。

它的逆条件是 \(\exists i \geq 2, a_i \geq A_1 q^{i}\) ,曲线可能会经过一个点以上。

\(q \leq \log_{i} \frac{a_i}{A_1} \leq \log_{2} M\) 可以限制出 \(q\) 的范围。于是需要 \(O(N \log M)\) 枚举一条曲线。

对于任意一个定点 \(a_i\) ,我们将记录它对 \((A_1 = \frac{a_i}{q^{i - 1}}, q)\) 的 \(b_i\) 贡献。维护 \(\{(A_1, q), value\}\) 。

这些曲线最后还要和 \(O(N)\) 条只经过一个点的曲线取更优值。

总时间复杂度为 \(O(N \log M)\) 。

标签:直线,一个点,函数,leq,枚举,2M,取点,初等,log
From: https://www.cnblogs.com/zsxuan/p/18331231

相关文章

  • PostgreSQL 之 to_timestamp函数
    to_timestamp是PostgreSQL中的一个函数,用于将字符串或数字转换为时间戳。以下是关于to_timestamp的详细介绍:引入版本to_timestamp函数在PostgreSQL7.3版本中引入。语法to_timestamp有两种主要的用法:1.将字符串转换为时间戳to_timestamp(text,text)第一......
  • 【C语言】输入、输出函数知识、getchar()、putchar()、 scanf()、printf()
    函数的声明和定义1.1 函数声明1.告诉编译器有一个函数叫什么,参数是什么,返回类型是什么。但是具体是不是存在,函数声明决定不了。2.函数的声明一般出现在函数的使用之前。要满足先声明后使用。3.函数的声明一般要放在头文件中的。1.2C本身是不提供输入输出功能的,需要......
  • 函数的学习(一)
    1.定义C语言的函数是一段可被重复调用的代码块,可以执行特定的任务并返回一个值。每个函数由函数头、函数体和函数返回值组成。2.函数的分类C语言中的函数可以根据不同的特性进行分类,常见的分类如下:(1)标准函数(库函数):这些函数是C语言提供的预定义函数,可以直接在程序中调用。标......
  • 随机数函数 和 猜数字游戏(c语言初学者拔高)
    目录1.随机数的生成方法1.1rand()函数1.1.1函数原型1.1.2函数功能1.2srand()函数1.2.1函数原型1.2.2函数功能1.3time()函数1.2.1函数原型1.1.2函数功能1.4设置随机数的范围2.猜数字游戏2.1普通版:结构逻辑解析2.1.1程序代码2.1.2 细节答疑2.2拓......
  • 【信息学奥赛提高组】简单、初等数论
    初等数论目录初等数论整除与约数带余除法和整除质数与约数算数基本定理公约数和公倍数更相减损术欧几里得算法(辗转相除法)裴蜀定理拓展欧几里得算法(Ex-GCD)同余同余方程逆元预处理逆元威尔逊定理完全剩余系费马小定理Miller-Rabin测试简化剩余系欧拉定理扩展欧拉定理欧拉函数中国剩......
  • Python 教程(六):函数式编程
    目录专栏列表前言函数定义参数返回值示例函数类型普通函数空函数匿名函数(Lambda函数)嵌套函数函数装饰器高阶函数函数参数位置参数默认参数可变位置参数可变关键字参数函数属性和方法`__name__``__doc__``func.__dict__``func.__defaults__``func.__annotations__`函......
  • c/c++ 《仿函数》
    4STL-函数对象4.1函数对象4.1.1函数对象概念概念:重载函数调用操作符的类,其对象常称为函数对象函数对象使用重载的()时,行为类似函数调用,也叫仿函数本质:函数对象(仿函数)是一个类,不是一个函数4.1.2函数对象使用特点:函数对象在使用时,可以像普通函数那样调用,可以......
  • 函数 动态参数
    #固定参数+动态位置参数defmy_function(a,b,*args):print(a)print(b)print(args)my_function(1,'c',1,2,3,4,5,6)#输出#1#固定位第一个占位符#c#固定位第二个占位符#(1,2,3,4,5,6)#剩下的部分#可变关键词参数defmy_funciton2(a,b,......
  • C语言中的函数(保姆级详细讲解)
    文章目录一.函数的概念1.1库函数1.2自定义函数二.函数的参数1.实参2.形参3.形参和实参的关系(传值调用)4.数组做函数参数(传址调用)三.函数的return语句四.函数的嵌套调用和链式访问1.嵌套调用2.链式访问五.static和extern1.作用域和生命周期2.static2.1s......
  • Lambda-Go:将函数式编程引入 Go
    Lambda-Go:将函数式编程引入Go原创 GoOfficialBlog GoOfficialBlog 2024年07月28日20:16 中国香港函数式编程是编程范式当中的一种,喜欢的人爱之如命,不喜欢的人嗤之以鼻,以简单高效著称的Go天然在函数式编程上有自己的优势。Lambda-Go[1] 是一个旨在将受Haskell......