整理的算法模板合集: ACM模板


目录

  • P4781 【模板】拉格朗日插值
  • 重心拉格朗日插值法
  • 拉格朗日插值法求系数
  • 自然数k次幂的和

点我看多项式全家桶(●’◡’●)


P4781 【模板】拉格朗日插值


我们按照上面的思路,带入n个点求一下f(k)f(k)f(k)即可。时间复杂度O(n2)O(n^2)O(n2)。

注意本题还要求逆元,为了防止求逆元的时间复杂度影响整体的时间复杂度,所以我们分别计算出分子和分母,再将分子乘进分母的逆元,累加进最后的答案,时间复杂度的瓶颈就不会在求逆元上,总体的时间复杂度为O(n2)O(n^2)O(n2)。

代码实现:

本题需要累乘,会爆int,记得开long long

Code

// Problem: P4781 【模板】拉格朗日插值
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P4781
// Memory Limit: 125 MB
// Time Limit: 1000 ms
//
// Powered by CP Editor (https://cpeditor.org)#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>using namespace std;const int N = 500007;
typedef long long ll;
const int mod = 998244353;
ll n, m, k;struct Point
{ll x, y;
}A[N];ll qpow(ll a, ll b, ll c)
{ll res = 1;while(b) {if(b & 1) res = res * a % c;a = a * a % c;b >>= 1;}return res;
}ll inv(ll x) {return qpow(x, mod - 2, mod);}int main()
{scanf("%lld%lld", &n, &k);for(int i = 1; i <= n; ++ i) {scanf("%lld%lld", &A[i].x, &A[i].y);}ll ans = 0;for(int i = 1; i <= n; ++ i) {ll s1 = A[i].y % mod;ll s2 = 1ll;for(int j = 1; j <= n; ++ j) {if(i != j) {s1 = s1 * (k - A[j].x) % mod;s2 = s2 * (A[i].x - A[j].x) % mod;}}ans += s1 * inv(s2) % mod;}printf("%lld\n", (ans % mod + mod) % mod);return 0;
}

我们使用拉格朗日插值公式,对于一个数 kkk ,我们很容易在 O(n2)O(n^2)O(n2) 时间求得 F(k)F(k)F(k) 的数值,如果 xix_ixi​ 是连续的,我们甚至可以利用预处理在 O(n)O(n)O(n) 时间内得到 F(k)F(k)F(k) 的数值。
但是如果 xix_ixi​ 不连续,又有多组查询,就需要得到这个多项式的系数以保证求一个函数值的时间为 O(n)O(n)O(n) 。

重心拉格朗日插值法

我们对拉格朗日插值公式进行优化:

f(x)=∑i=1nyi∏j≠ix−xjxi−xjf(x)=\sum_{i=1}^n y_i\prod_{j\neq i}\dfrac {x-x_j} {x_i-x_j}f(x)=i=1∑n​yi​j​=i∏​xi​−xj​x−xj​​

设 h=∏i=1nx−xih=\prod_{i=1}^n x-x_ih=i=1∏n​x−xi​
带入得:
=h∑i=1n∏j≠iyi(xi−xj)(x−xi)=h\sum_{i=1}^n \prod_{j\neq i}\dfrac {y_i} {(x_i-x_j)(x-x_i)}=hi=1∑n​j​=i∏​(xi​−xj​)(x−xi​)yi​​


ti=∏j≠iyixi−xjt_i=\prod_{j\neq i} \dfrac {y_i} {x_i-x_j}ti​=j​=i∏​xi​−xj​yi​​

带入得:

=h∑i=1ntix−xi=h\sum_{i=1}^n \dfrac {t_i} {x-x_i}=hi=1∑n​x−xi​ti​​

每次加入一个新点时,计算出它的 tit_iti​ ,并且更新别的点的 tit_iti​ ,时间复杂度 O(n)O(n)O(n),加入 nnn 个点就是 4n^2$ 。

求解时, O(n)O(n)O(n) 求 hhh ,O(n)O(n)O(n) 求出那个 ∑\sum∑,时间复杂度 O(n)O(n)O(n)。

拉格朗日插值法求系数

首先观察式子,发现对于每个 iii , 上面部分是 (x−x1)×(x−x2)…×(x−xn)(x−xi)\cfrac{(x-x_1) \times (x-x_2)… \times (x-x_n)}{(x-x_i)}(x−xi​)(x−x1​)×(x−x2​)…×(x−xn​)​, 下面那部分和 yiy_iyi​ 都是常数。

所以可以 O(n2)O(n^2)O(n2) 处理出(x−x1)×(x−x2)…×(x−xn)(x-x_1) \times (x-x_2)… \times (x-x_n)(x−x1​)×(x−x2​)…×(x−xn​) 这个 nnn 次多项式,然后通过模拟长除法,O(n)O(n)O(n)时间内可以得到(x−x1)×(x−x2)…×(x−xn)(x−xi)\cfrac{(x-x_1) \times (x-x_2)… \times (x-x_n)}{(x-x_i)}(x−xi​)(x−x1​)×(x−x2​)…×(x−xn​)​,然后常系数直接 O(n)O(n)O(n) 暴力算出来,就得到了 xix_ixi​ 对应的多项式,最后把所有多项式加起来就得到了最终的系数。

// Problem: P4781 【模板】拉格朗日插值
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P4781
// Memory Limit: 125 MB
// Time Limit: 1000 ms
//
// Powered by CP Editor (https://cpeditor.org)#include <bits/stdc++.h>
using namespace std;
#define int long long
#define ll long long
const int N = 5007, mod = 998244353;int n, m, k;
int a[N], b[N], c[N], f[N], tmp[N], x[N], y[N];int qpow(int a, int b)
{int res = 1;while(b) {if(b & 1) res = 1ll * res * a % mod;a = 1ll * a * a % mod;b >>= 1;}return res % mod;
}int inv(int x)
{return qpow(x, mod - 2);
}void mul(ll *f, int len, ll t, int n) { //len为多项式的次数+1,f -> f*(x+t)for (int i = len; i > 0; -- i)tmp[i] = f[i], f[i] = f[i - 1];tmp[0] = f[0], f[0] = 0;for (int i = 0; i <= len; ++ i)f[i] = (f[i] + t * tmp[i]) % mod;
}
void dev(ll *f, ll *r, ll t, int n) { //f是被除多项式的系数,r = f/(x+t)for (int i = 0; i <= n; ++ i)tmp[i] = f[i];for (int i = n; i > 0; -- i) {r[i - 1] = tmp[i];tmp[i - 1] = (tmp[i - 1] - t * tmp[i] + mod) % mod;}return;
}//计算n次多项式 f_x = ∑{0~n-1} (a_i * x^i) 的 a_0 ~ a_{n - 1} (n次多项式系数)
void lagrange(int n) {  memset(a, 0, sizeof a);b[1] = 1, b[0] = -x[1];for (int i = 2; i <= n; ++i) {mul(b, i, -x[i], n);}//预处理(x-x1)*(x-x2)...*(x-xn)for (int i = 1; i <= n; ++i) {ll fz = 1;for (int j = 1; j <= n; ++j) {if (j == i)continue;fz = (fz * (x[i] - x[j]) + mod) % mod;}fz = qpow(fz, mod - 2);fz = fz * y[i] % mod; //得到多项式系数dev(b, c, -x[i], n);//得到多项式,保存在b数组for (int j = 0; j < n; ++j)a[j] = (a[j] + fz * c[j] % mod + mod) % mod;}
} signed main()
{scanf("%lld%lld", &n, &k);for(int i = 1; i <= n; ++ i) {scanf("%lld%lld", &x[i], &y[i]);}lagrange(n);int ans = 0;int kpow = 1;for(int i = 0; i < n; ++ i) {ans = (ans + kpow * a[i] % mod) % mod;kpow = kpow * k % mod;} printf("%lld\n", ans);return 0;
}

自然数k次幂的和

求 ∑i=1nik\sum_{i=1}^n i^k∑i=1n​ik ,n≤109,k≤106n \leq 10^9,k \leq 10^6n≤109,k≤106

Solution

n=k+2n=k+2n=k+2

// Problem: B. Morning Jogging
// Contest: Codeforces - Contest 2050 and Codeforces Round #718 (Div. 1 + Div. 2)
// URL: https://codeforces.com/contest/1517/problem/B
// Memory Limit: 256 MB
// Time Limit: 1000 ms
//
// Powered by CP Editor (https://cpeditor.org)#include <bits/stdc++.h>
using namespace std;const int N = 1100007, mod = 1e9 + 7;int read(){int s = 0, ne = 1; char c = getchar();while(c < '0' || c > '9') {if(c == '-') ne = -1; c = getchar();}while(c >= '0' && c <= '9') s = (s << 1) + (s << 3) + c - '0', c = getchar();return s * ne;
}int qpow(int a, int b)
{int res = 1;while(b) {if(b & 1) res = 1ll * res * a % mod;a = 1ll * a * a % mod; b >>= 1;} return res;
}int n, k;
int s[N], pre[N], suf[N], infact[N], fact[N], ans;void init()
{infact[0] = fact[0] = 1;for(int i = 1; i <= k + 10; ++ i)fact[i] = 1ll * fact[i - 1] * i % mod;infact[k + 10] = qpow(fact[k + 10], mod - 2);for(int i = k + 9; i >= 0; -- i)  infact[i] = 1ll * infact[i + 1] * (i + 1) % mod;infact[0] = 1;for(int i = 1; i <= k + 2; ++ i)s[i] = (s[i - 1] + qpow(i, k)) % mod;
}int main()
{scanf("%d%d", &n, &k);init();if(n <= k + 2) {printf("%d", s[n]);return 0;}pre[0] = 1;for(int i = 1; i <= k + 2; ++ i)pre[i] = 1ll * pre[i - 1] * (n - i) % mod;suf[k + 3] = 1;for(int i = k + 2; i; -- i)suf[i] = 1ll * suf[i + 1] * (n - i) % mod;for(int i = 1; i <= k + 2; ++ i) {s[i] = 1ll * s[i] * pre[i - 1] % mod * suf[i + 1] % mod * infact[i - 1] % mod * infact[k + 2 - i] % mod;if((k + 2 - i) & 1) ans = (1ll * ans - s[i] + mod) % mod;else ans = (1ll * ans + s[i]) % mod;}printf("%d\n", ans);
}

拉格朗日插值法 在ACM竞赛中的一些应用

https://blog.csdn.net/qq_41157137/article/details/100593260?utm_medium=distribute.pc_relevant.none-task-blog-baidujs_title-1&spm=1001.2101.3001.4242

【学习笔记】拉格朗日插值相关推荐

  1. 一、Vue基础语法学习笔记系列——插值操作(Mustache语法、v-once、v-html、v-text、v-pre、v-cloak)、绑定属性v-bind(绑定class、style)、计算属性

    一.插值操作 1. Mustache 如何将data中的文本数据,插入到HTML中呢? 我们已经学习过了,可以通过Mustache语法(也就是双大括号). Mustache: 胡子/胡须. 我们可以像 ...

  2. [学习笔记]拉格朗日中值定理

    其实OI中暂时没有用过? 爆切GK2018压轴题踩标算 http://www.360doc.com/content/18/0101/05/50036269_718043946.shtml 转载于:ht ...

  3. [学习笔记]拉格朗日插值法求多项式系数

    一.引入 我们会遇到这样的问题: 给定 nnn 个点 (xi,yi)" role="presentation" style="position: relativ ...

  4. 凸优化学习笔记 11:对偶原理 拉格朗日函数

    前面讲了凸优化问题的定义,以及一些常见的凸优化问题类型,这一章就要引入著名的拉格朗日函数和对偶问题了.通过对偶问题,我们可以将一些非凸问题转化为凸优化问题,还可以求出原问题的非平凡下界,这对复杂优化问 ...

  5. 【数值分析】学习笔记4——凸优化2:拉格朗日函数及变分不等式(Variational Inequality,VI)

    目录 前言 一.线性约束的凸优化问题(一个凸函数+线性约束条件) 1.一个实例 2.对偶问题 二.拉格朗日函数与鞍点 1.拉格朗日函数 2.鞍点 三.变分不等式(Variational Inequal ...

  6. 【12月学习进度3/31—计算机图形学期末准备01】拉格朗日插值 + 三次Hermite插值

    相关概念 型值点:事先给定的离散点 插值:得到的曲线通过所有的型值点 逼近:不要求通过给定的所有型值点,用给定型值点控制曲线形状 Hermite多项式 拉格朗日插值 拉格朗日插值是当 j=0j=0j= ...

  7. 拉格朗日插值的优缺点_「笔记」拉格朗日插值

    简介 对于 \(k\) 次多项式函数 \(F(x)\). 若已知 \(k+1\) 个点值,则可构造出多项式. 有: \[F(x) = \sum_{i=1}^{k+1}y_i\prod_{i\not = ...

  8. rstudio拉格朗日插值法_拉格朗日插值法学习笔记

    拉格朗日插值法是一个根据点对求回原函数的算法,原理挺好懂的. 原理和优化方法上面的大佬都讲得很好. 其实主要就是这个式子: 然后暴力算这个式子的话是每求一项f(k)的时间复杂度都是n^2. 这个时间很 ...

  9. 拉格朗日插值法学习笔记

    文章目录 STEP1 问题引入 STEP2 拉格朗日插值公式 存在性 唯一性 代码模板 STEP3 算法优化 重心拉格朗日插值 xxx连续取值的情况 STEP4 经典例题 The Sum of the ...

最新文章

  1. 华人博士提出原型对比学习,非监督学习效果远超MoCo和SimCLR
  2. 数组常用解题方法(持续更新)
  3. SpringMVC + MyBatis整合 【转】
  4. Delphi 复习代码
  5. Django从理论到实战(part46)--View类
  6. linux java jar打包_【Java】Java程序打包成jar包在Linux上运行
  7. 作者:张澄(1979-),男,中国联合网络通信有限公司江苏省分公司互联网部大数据中心总监...
  8. 哪吒之魔童降世视听语言影评_豆瓣评分8.7,这个“新哪吒”不一般|《哪吒之魔童降世》影评...
  9. ARMLINUX学习笔记(二)
  10. iosApp上传app遇到的问题
  11. mysql pgsql 语法_PostgreSQL ALIAS语法
  12. java 算数运算符
  13. 解决Cell重用问题
  14. 裁判文书网数据采集爬虫2021-08
  15. python处理grd格式文件_Surfer的grd文件格式说明
  16. 基音检测算法的性能:Performance Evaluation of Pitch Detection Algorithms
  17. 【无标题】 二手车汽车资质认证 二手车汽车资质认证
  18. Navicat的安装及免费使用方式
  19. java swing 自动补全_扩展easyui的combobox组件的自动完成(autocomplete)
  20. javascript 中的纯函数

热门文章

  1. 使用PixelLib来实现图像分割
  2. OpenCV实现失焦模糊图像恢复
  3. 利用CNN来检测伪造图像
  4. 墙裂建议收藏,100道Python练手题目
  5. Js 向json对象中添加新元素
  6. bootstrap课程1 bootstrap为什么这么火
  7. 所有企业要注意了,你随时可能掉进GDPR这个坑里!
  8. 域名跳转301-LAMP环境搭建
  9. OC高效率52之理解消息转发机制
  10. Silverlight+WCF 新手实例 象棋 主界面-实时聊天区(二十五)