zoukankan      html  css  js  c++  java
  • 拉格朗日插值模板题 luoguP4871

    学习博客

    拉格朗日插值 (O(n^{2}))
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #include<map>
    #include<queue>
    #include<vector>
    #include<string>
    #include<fstream>
    
    using namespace std;
    typedef long long ll;
    const int N = 4e6 + 105;
    const int mod = 998244353;
    const double Pi = acos(- 1.0);
    const int INF = 0x3f3f3f3f;
    
    int n, k;
    int x[N], y[N];
    
    int sub(const int& a, const int& b){
    	int t = a - b;
    	return t < 0 ? t + mod : t;
    }
    
    
    int inv(int x){
    	int res = 1;
    	int p = mod - 2;
    	for(; p; p >>= 1, x = 1ll * x * x % mod)
    		if(p & 1) res = 1ll * res * x % mod;
    	return res;
    }
    
    
    int Lagrange(int n, int x[], int y[], int k){
    	int res = 0;
    	for(int i = 1; i <= n; ++ i){
    		int s1 = 1, s2 = 1;	//s1:分子,s2:分母
    		for(int j = 1; j <= n; ++ j){
    			if(i != j){
    				s1 = 1ll * s1 * sub(k, x[j]) % mod;
    				s2 = 1ll * s2 * sub(x[i], x[j]) % mod;
    			}
    		}
    		res = (res + 1ll * y[i] * s1 % mod * inv(s2) % mod) % mod; 
    	}
    	return res;
    }
    
    int main()
    {
    	scanf("%d%d",&n,&k);
    	for(int i = 1; i <= n; ++ i) scanf("%d%d",&x[i],&y[i]);
    	printf("%d
    ", Lagrange(n, x, y, k));
    	return 0;
    }
    
    
    在 x 取值连续时的拉格朗日插值法 (O(nlog^{n}))

    如果预处理逆元可以(O(n))

    int n, k;
    int pre[N], suf[N], fac[N];
    
    int qpow(int x, int y){
    	int res = 1;
    	while(y){
    		if(y & 1) res = 1ll * res * x % mod;
    		x = 1ll * x * x % mod;
    		y >>= 1;
    	}
    	return res;
    }
    
    int Lagrange(int n, int x[], int y[], int k){
    	int res = 0;
    	pre[0] = suf[n + 1] = fac[0] = 1;
    	for(int i = 1; i <= n; ++ i) pre[i] = 1ll * pre[i - 1] * (k - i) % mod;
    	for(int i = n; i >= 1; -- i) suf[i] = 1ll * suf[i + 1] * (k - i) % mod;
    	for(int i = 1; i <= n; ++ i) fac[i] = 1ll * fac[i - 1] * i % mod;
    	for(int i = 1; i <= n; ++ i){
    		int s1 = (pre[i - 1] * suf[i + 1]) % mod;
    		int s2 = (fac[i - 1] * fac[n - i]) % mod;
    		if((n - i) & 1) s2 = (mod - s2) % mod;
    		res = (1ll * res + 1ll * y[i] * s1 % mod * qpow(s2, mod - 2) % mod) % mod;
    	}
    	return res;
    }
    
    
  • 相关阅读:
    2017-2018-1 20155225 《信息安全系统设计基础》第三周学习总结
    2017-2018-1 20155225 《信息安全系统设计基础》第2周课堂实验
    20155225 2017-2018-1 《信息安全系统设计基础》第一周学习总结
    课堂实践——数据库
    20155225 2016-2017-2《Java程序设计》课程总结
    20155225 实验五《网络编程与设计》实验报告
    20155225 实验四《Android程序设计》实验报告
    转载
    HDU
    SCU
  • 原文地址:https://www.cnblogs.com/A-sc/p/12777358.html
Copyright © 2011-2022 走看看