hdu5275 (插值法)
来源:互联网 发布:数据录入项目外包 编辑:程序博客网 时间:2024/05/17 03:25
首先要明确,所谓插值,就是多项式的点值表达式转系数表达式。
对于n个x不相同的点(xi,yi),可以唯一确定一个阶为n的多项式
一般的,有两种常用的插值方法:
1.拉格朗日插值法
直接构造多项式
简单粗暴,证明只需要把
2.牛顿插值
虽然拉格朗日插值法比较简单也便于记忆,但对于一些要对子串进行插值的题目,牛顿插值显然更加方便
令
注意对于
定义
根据定义进行计算可以发现
更进一步的,假如你想对
对应插值所得的系数就是
对于上面插值的理解,可以参考我hdu5275的代码
首先是很适合给子串插值的牛顿插值
#include<bits/stdc++.h>using namespace std;typedef long long Int;const int M=1e9+7;int rev[250002];int dp[3002][3002];int x[3002],y[3002];inline int getrev(int x){return x<0?-rev[-x]:rev[x];}int main(){ rev[1]=1; for(int i=2;i<=250000;i++)rev[i]=(M-M/i)*(Int)rev[M%i]%M; int n; while(scanf("%d",&n)!=EOF) { for(int i=1;i<=n;i++)scanf("%d%d",x+i,y+i); for(int i=1;i<=n;i++)dp[0][i]=y[i]; for(int i=1;i<=n;i++) for(int j=1;j+i<=n;j++) dp[i][j]=((dp[i-1][j+1]-dp[i-1][j])*(Int)getrev(x[i+j]-x[j])%M+M)%M; int m;scanf("%d",&m); while(m--) { int l,r,q;scanf("%d%d%d",&l,&r,&q); int ans=0,cur=1; for(int i=0;i<=r-l;i++) { ans+=dp[i][l]*(Int)cur%M; if(ans>=M)ans-=M; cur=(cur*(Int)(q-x[l+i])%M+M)%M; }printf("%d\n",ans); } }}
然后是拉格朗日插值法,对于本题需要一些观察和技巧
#include<bits/stdc++.h>using namespace std;const int Maxn=3002,M=1e9+7;typedef long long Int;int x[Maxn],y[Maxn];int n,m;int dp[Maxn][Maxn];int rev[250002],frev[250002];int powmod(int x,int y){ int t=x,ret=1; while(y) { if(y&1)ret=ret*(Int)t%M; y>>=1; t=t*(Int)t%M; } return ret;}inline int getrev(int x){ if(x<0)return frev[-x]; return rev[x];}int main(){ for(int i=1;i<=250000;i++)rev[i]=powmod(i,M-2),frev[i]=powmod(M-i,M-2); while(scanf("%d",&n)!=EOF) { for(int i=1;i<=n;i++)scanf("%d%d",x+i,y+i); scanf("%d",&m); for(int i=1;i<=n;i++) { dp[i][i]=1; for(int j=i-1;j>=1;j--)dp[i][j]=dp[i][j+1]*(Int)getrev(x[i]-x[j])%M; for(int j=i+1;j<=n;j++)dp[i][j]=dp[i][j-1]*(Int)getrev(x[i]-x[j])%M; } while(m--) { int l,r,q; scanf("%d%d%d",&l,&r,&q); int cs=-1,ans=0; int tot=1; for(int i=l;i<=r;i++) { if(x[i]!=q)tot=((q-x[i])*(Int)tot%M+M)%M; else{cs=i;} } if(cs!=-1) { ans=y[cs]*(Int)dp[cs][l]%M*dp[cs][r]%M*tot%M; } else { for(int k=l;k<=r;k++) { ans+=y[k]*(Int)dp[k][l]%M*dp[k][r]%M*tot%M*getrev(q-x[k])%M; if(ans>=M)ans-=M; } }printf("%d\n",ans); } }}
0 0
- hdu5275 (插值法)
- 插值法
- Hermite插值法
- 牛顿插值法
- 插值法排序
- 插值法查找
- 牛顿插值法
- 牛顿插值法
- Lagrange插值法
- 众数插值法
- 牛顿插值法
- 插值法查找
- 多项式插值法
- 牛顿插值法
- 代数插值法概念
- Java实现lagrange 插值法
- 数值计算之插值法
- 插值法之三次样条插值
- UVa-512(经典栈)
- ImageLoader 线程池 单例 使用模板
- 【NGUI】NGUI血条制作,当人物移出屏幕后不显示血条,优化代码
- c3p0的DriverManagerDataSource源代码看单例
- LeetCode Simplify Path
- hdu5275 (插值法)
- action与servlet API ModelDriven接口 异常
- 关于File的一点东西
- Java随机验证吗
- LeetCode Set Matrix Zeroes
- jquery操作select(取值,设置选中) 取得已选的值
- 单例模式 - 创建者模式
- 有关Google面试的资料集合
- android edittext + listview 实现搜索listview中的内容