杂烩QAQ

前言

这篇 b l o g blog blog 仅仅记录一下之前学的一些比较简单的东西,为了防止忘记。所以有不详细的地方请谅解QAQ。

拉格朗日插值

给出平面上的 n + 1 n+1 n+1 个点 ( x i , y i ) ( 0 ≤ i ≤ n ) (x_i,y_i)(0\leq i\leq n) (xi,yi)(0in),找到一个 n n n 次多项式 f ( x ) f(x) f(x),使得这个多项式过这 n + 1 n+1 n+1 个点,给出一个 k k k,求 f ( k ) f(k) f(k) n ≤ 5000 n\leq 5000 n5000
天才滴拉格朗日构造出了这个多项式(这里就不细究是怎么构造出来的了>_<):
f ( k ) = ∑ y = 0 n y i ∏ i ≠ j k − x j x i − x j f(k)=\sum\limits_{y=0}^{n}y_i\prod\limits_{i\neq j}\dfrac{k-x_j}{x_i-x_j} f(k)=y=0nyii=jxixjkxj
容易验证 y i = f ( x i ) y_i=f(x_i) yi=f(xi)(读者自证不难,而且 f ( x ) f(x) f(x) 是关于 x x x n n n 次多项式。
于是我们可以在 O ( n 2 ) O(n^2) O(n2) 复杂度完成插值。如果预处理出 ∏ i ≠ j 1 x i − x j \prod\limits_{i\neq j}\dfrac{1}{x_i-x_j} i=jxixj1,就可以 O ( n ) O(n) O(n) 完成插值!

拉格朗日插值的一个应用

1 k + 2 k + . . . + n k 1^k+2^k+...+n^k 1k+2k+...+nk。其中, n ≤ 1 0 15 , k ≤ 1 0 7 n\leq 10^{15},k\leq 10^7 n1015,k107
组队赛出了这个我居然不会,太丢人了…

小学知识,自然数 k k k 次幂的前缀和是一个 k + 1 k+1 k+1 次多项式,于是可以通过前 k + 2 k+2 k+2 个点插出这个多项式。
问题在于,怎么 O ( k ) O(k) O(k) f ( x ) = ∑ y = 0 n y i ∏ i ≠ j x − x j x i − x j f(x)=\sum\limits_{y=0}^{n}y_i\prod\limits_{i\neq j}\dfrac{x-x_j}{x_i-x_j} f(x)=y=0nyii=jxixjxxj
事实上,由于 x x x 坐标是连续的,我们可以将原式写成:
f ( x ) = ∑ y = 0 n y i ∏ i ≠ j x − j i − j f(x)=\sum\limits_{y=0}^{n}y_i\prod\limits_{i\neq j}\dfrac{x-j}{i-j} f(x)=y=0nyii=jijxj
然后呢,我们考虑优化连乘部分。
上面的 ∏ i ≠ j x − j \prod\limits_{i\neq j}x-j i=jxj,可以写成 ∏ j = 0 k + 1 x − j x − i \dfrac{\prod\limits_{j=0}^{k+1}x-j}{x-i} xij=0k+1xj,于是可以预处理。
下面的 ∏ i ≠ j i − j \prod\limits_{i\neq j}i-j i=jij,我们拆成两部分,变成 ( ∏ j = 0 i − 1 ( i − j ) ) × ( ∏ j = i + 1 k + 1 ( i − j ) ) (\prod\limits_{j=0}^{i-1}(i-j))\times(\prod\limits_{j=i+1}^{k+1}(i-j)) (j=0i1(ij))×(j=i+1k+1(ij)),前面那部分就是 i ! i! i!(这里是阶乘的意思,不是感叹号!),后面那部分就是 ( − 1 ) k − i + 1 ( k − i + 1 ) ! (-1)^{k-i+1}(k-i+1)! (1)ki+1(ki+1)!
于是预处理阶乘和阶乘的逆,就可以实现 O ( k ) O(k) O(k) 插值了!

点分治

点分治算法算是分治思想在树上的一个重大应用,不过其只能用于无根树QAQ。
点分治一般解决的是树上的路径问题。我们考虑当前的一棵子树,那么路径可以分为两种,一种是经过根节点的,一种是在他的子树中的。
第二种可以递归解决,如果可以在 O ( 子 树 大 小 ) O(子树大小) O() 的复杂度求出第一种的路径,那么我们就可以在 O ( n l o g n ) O(nlogn) O(nlogn) 总复杂度求解这个问题。(这里我讲的很不详细,建议读者自行做题理解>_<)
具体做法是每次求出子树的重心,以子树的重心为根解决子问题(由于这棵树是无根树,所以这种做法是可行的),不难证明,最多只会递归 l o g n logn logn 层。
复杂度是 O ( n l o g n ) O(nlogn) O(nlogn) 的,详情可以参考主定理。
不过呢,我们可以考虑一种极端情况,就是满二叉树的情况。那么 T ( n ) = 2 T ( n 2 ) + n T(n)=2T(\dfrac{n}{2})+n T(n)=2T(2n)+n,可以看出复杂度是 O ( n l o g n ) O(nlogn) O(nlogn) 的。

可并堆

什么?你以为我要讲左偏树?那是不可能滴!因为我还没学
这里介绍的是一种黑科技,就是 p b d s pb_ds pbds 库里面的配对堆,其用法非常简单,而且效率和左偏树差不多(稍慢一点)。
用法大概就是:

#include <ext/pb_ds/priority_queue.hpp>
using namespace __gnu_pbds;
typedef __gnu_pbds::priority_queue<int, greater<int>, pairing_heap_tag> Heap;

常用操作:

push()  //会返回一个迭代器
top()  //同 stl 
size()  //同 stl 
empty() //同 stl 
clear()  //同 stl 
pop()  //同 stl 
join(priority_queue &other)  //合并两个堆,other会被清空
split(Pred prd,priority_queue &other)  //分离出两个堆
modify(point_iterator it,const key)  //修改一个节点的值

一般左偏树能做的题都能用这个来做,除了部分需要可持久化的题目。

线段树合并

咕咕咕

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值