首页 > 其他分享 >P5667 拉格朗日插值2

P5667 拉格朗日插值2

时间:2024-02-13 15:55:25浏览次数:21  
标签:拉格朗 le P5667 插值 dfrac sum len int underline

由拉格朗日插值公式得:

\[f(x) = \sum_{i = 0}^nf(i)\prod_{j \ne i}\dfrac{x - j}{i - j} = \sum_{i = 0}^n\dfrac{f(i)x^{\underline{n+1}}}{(-1)^{n-i}i!(n - i)!(x - i)} \]

我们要把函数平移 \(m\) 个单位长度,所以要写 \(f(x + m)\) 的式子,即

\[f(x + m) = \sum_{i = 0}^n\dfrac{f(i)(x+m)^{\underline{n+1}}}{(-1)^{n-i}i!(n - i)!(x + m - i)} \]

记 \(A(x) = \begin{cases}\frac{f(x)}{(-1)^{n-x}x!(n - x)!} & x \le n \\ 0 & x > n\end{cases}, B(x) = \dfrac1{x + m}, F = A * B\)。

当 \(x \le n\) 时,有:

\[F(x) = \sum_{i=0}^xA(i)B(x - i) = \sum_{i = 0}^x\dfrac{f(i)}{(-1)^{n-i}i!(n-i)!(x+m-i)} \]

你会发现这样少算了 \([x + 1, n]\) 里的信息,所以 \(B(x)\) 需要平移一下,变为 \(B(x) = \dfrac1{x + m - n}\)。

对于 \(x \le n\),有:

\[F(x+n) = \sum_{i=0}^nA(i)B(x+n-i) = \sum_{i=0}^n\dfrac{f(i)}{(-1)^{n-i}i!(n-i)!(x+m-i)} \]

所以有

\[f(x + m) = (x+m)^{\underline{n+1}}F(x+n) \]

时间复杂度 \(\mathcal O(n \log n)\)。

代码

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

constexpr int N = 1 << 19, MOD = 998244353;

int n, m, f[N], A[N], B[N], F[N];
int bits, len, rev[N], Wn[2][19];
ll invfct[N], down[N];

ll qp(ll base, int e) {
    ll res = 1;
    while (e) {
        if (e & 1) res = res * base % MOD;
        base = base * base % MOD;
        e >>= 1;
    }
    return res;
}

inline void init(int n) {
    bits = -1, len = 1; while (len < n) len <<= 1, bits++;
    for (int i = 0; i < len; i++) rev[i] = (rev[i >> 1] >> 1) | ((i & 1) << bits);
}

void NTT(int *A, bool I = 0) {
    for (int i = 0; i < len; i++) if (i < rev[i]) swap(A[i], A[rev[i]]);
    for (int i = 1; i < len; i <<= 1) {
        ll wn = Wn[I][__builtin_ctz(i)];
        for (int j = 0; j < len; j += (i << 1)) {
            ll w = 1;
            for (int k = j; k < j + i; k++) {
                int t = w * A[k + i] % MOD;
                A[k + i] = (A[k] - t + MOD) % MOD, A[k] = (A[k] + t) % MOD;
                w = w * wn % MOD;
            }
        }
    }
    if (I) {
        ll invlen = qp(len, MOD - 2);
        for (int i = 0; i < len; i++) A[i] = A[i] * invlen % MOD;
    }
}

int main() {
    ios_base::sync_with_stdio(0); cin.tie(nullptr), cout.tie(nullptr);
    cin >> n >> m;
    for (int i = 0; i <= n; i++) cin >> f[i];

    for (int i = 0; i < 19; i++) Wn[0][i] = qp(3, (MOD - 1) / (1 << (i + 1))), Wn[1][i] = qp(Wn[0][i], MOD - 2);
    invfct[0] = 1; for (int i = 1; i <= n; i++) invfct[i] = invfct[i - 1] * i % MOD;
    for (int i = 2; i <= n; i++) invfct[i] = qp(invfct[i], MOD - 2);
    down[0] = 1; for (int i = m; i >= m - n; i--) down[0] = down[0] * i % MOD;
    for (int i = 1; i <= n; i++) down[i] = down[i - 1] * qp(m - n + i - 1, MOD - 2) % MOD * (m + i) % MOD;

    for (int i = 0; i <= n; i++) {
        A[i] = f[i] * invfct[i] % MOD * invfct[n - i] % MOD;
        if ((n ^ i) & 1) A[i] = MOD - A[i];
    }
    for (int i = 0; i <= (n << 1); i++) B[i] = qp(i + m - n, MOD - 2);

    init((n << 1) + 1); NTT(A), NTT(B);
    for (int i = 0; i < len; i++) F[i] = (ll)A[i] * B[i] % MOD;
    NTT(F, 1);
    for (int i = 0; i <= n; i++) cout << down[i] * F[i + n] % MOD << ' ';
    return 0;
}

标签:拉格朗,le,P5667,插值,dfrac,sum,len,int,underline
From: https://www.cnblogs.com/chy12321/p/18014619

相关文章

  • 拉格朗日插值学习笔记
    拉格朗日插值第一步:子函数\(f_i(x)=\begin{cases}1&x=x_i\\0&x=x_j(i\nej)\end{cases}\)由此可得:\(f(x)=\sum\limits_{i=1}^ny_if_i(x)\)第二步:对于\(f_i(x)\),要满足当\(x=x_i\)时,\(y=1\),而\(x\nex_i\)时,\(y=0\)故:\(f_i(x)=\dfrac{\prod\limits_{j=1,j\......
  • 拉格朗日插值学习笔记
    拉格朗日插值定义给定一个多项式函数过点\((x_i,y_i)\),求出这个多项式函数的在\(x=k\)时的取值。公式\[f(k)=\sum_{i=0}^ny_i\prod_{j\not=i}\dfrac{k-x_j}{x_i-x_j}\]时间复杂度\(O(n^2)\)横坐标连续的拉格朗日插值在横坐标连续的情况下,可以做到\(O(n)\)插值。\[\b......
  • 数学建模入门笔记(3) 插值与拟合
    插值与拟合插值和拟合的区别:拟合不要求过每一个已知点,而插值要求过每一个已知点,因而插值可以看作过每一个点的拟合。插值适用于补全缺失值,因为使用一般拟合就有可能使已知值偏移,不符合需求。据说PS用某种样条插值,放大的时候最大程度的保留连续性,因此显得不是那么模糊.数学建模......
  • C# 字符串操作指南:长度、连接、插值、特殊字符和实用方法
    字符串用于存储文本。一个字符串变量包含由双引号括起的字符集合示例://创建一个string类型的变量并赋予一个值stringgreeting="Hello";如果需要,一个字符串变量可以包含多个单词:示例:stringgreeting2="Nicetomeetyou!";字符串长度在C#中,字符串实际上是一......
  • qt c语言双三次线性插值
    用chatgpt生成的测试了比较卡for(inty=0;y<enlargedHeight;y++){for(intx=0;x<enlargedWidth;x++){//计算原始图像中对应的浮点坐标floatoriginalX=(float)x/(float)enlar......
  • 数字信号处理-序列的抽取与插值
    0前言期中考好像就这里没考好呢,一看就是之前没好好听课没好好预习复习,到期中考也没弄懂这里(甚至发现作业题都忘记写了,那段时间忙比赛去了,真是得不偿失),所以才不会。1序列抽取序列的$D$抽取$x_d(n)=x(Dn)$,$D$为整数,叫抽取因子意义:每个连贯的D抽样中抽一个样值,从而减小数据量......
  • 拟合_插值_平滑曲线- 贝塞尔曲线
    平滑与拟合平滑后的曲线,一定经过原始的数据点,而拟合曲线,则不一定要经过原始数据点.时间序列的单值数据和时间序列的二维数据时间序列的单值数据--样条插值就可以轻松实现平滑最小二乘拟合非线性拟合还有分段拟合(样条拟合)非线性拟合还有分段拟合(样条拟合)插值......
  • games101-2 透视深度插值矫正与抗锯齿分析
    透视深度插值矫正与抗锯齿分析深度插值的差错原因透视深度插值公式推导games101中的错误msaa与ssaa简要定义games101中ssaa的实现games101中msaa的实现深度插值的差错原因当投影的图形与投影的平面不平行时,这时进行透视投影,从上图中可以看出,投影平面上的线段时均匀......
  • 数学建模之插值法及代码
    发现更多知识,欢迎访问Cr不是铬的个人网站引言数模比赛中,常常需要根据已知的函数点进行数据、模型的处理和分析,而有时候现有的数据是极少的,不足以支撑分析的进行,这时就需要使用一些数学的方法,“模拟产生”一些新的但又比较靠谱的值来满足需求,这就是插值的作用。插值法的定义......
  • 数学基础:三角形重心坐标插值公式的证明
    在快速Phong明暗处理(Blinn-Phong明暗处理)时,出现了三角形重心坐标插值公式,但没有给出证明.网上也鲜有证明过程,这里给出证明.问题描述:在三角形ABC中,三顶点A、B、C坐标分别为\((x_1,y_1,z_1)、(x_2,y_2,z_2)、(x_3,y_3,z_3)\).则三角形内任一点P(x,y,z)可表示为:\[\tag{1}P=\alph......