zoukankan      html  css  js  c++  java
  • LOJ #165. 拉格朗日插值

    重心拉格朗日插值模板题。

    用上面那篇文章的公式计算。插入时更新每个 (w_i),询问时分别 (O(n)) 计算 (l(k))(sumlimits_{i=1}^n frac{w_i}{k-x_i}) 即可。注意使用上述公式时 (k-x_i) 不能为 (0),所以我们要特判 (k=x_i) 的情况。

    代码:

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<iostream>
    #define int long long
    
    using namespace std;
    
    const int N=3009,M=998244353;
    int n,cnt,x[N],y[N],w[N];
    
    void init()
    {
    	scanf("%lld",&n);
    }
    
    int ksm(int a,int b)
    {
    	int res=1;
    	while(b)
    	{
    		if(b&1)
    			res=res*a%M;
    		b>>=1,a=a*a%M;
    	}
    	return res;
    }
    
    void work()
    {
    	int opt,X,Y;
    	while(n--)
    	{
    		scanf("%lld",&opt);
    		if(opt==1)
    		{
    			scanf("%lld %lld",&X,&Y);
    			x[++cnt]=X,y[cnt]=w[cnt]=Y;
    			for (int i=1;i<cnt;i++)
    				w[i]=w[i]*ksm(x[i]-x[cnt],M-2)%M,
    				w[cnt]=w[cnt]*ksm(x[cnt]-x[i],M-2)%M;
    		}
    		else
    		{
    			scanf("%lld",&X);
    			int flag=0;
    			for (int i=1;i<=cnt;i++)
    				if(X==x[i])
    				{
    					flag=1,printf("%lld
    ",y[i]);
    					break;
    				}
    			if(flag) continue;
    			int tmp=1,_tmp=0;
    			for (int i=1;i<=cnt;i++)
    				tmp=tmp*(X-x[i])%M;
    			for (int i=1;i<=cnt;i++)
    				_tmp=(_tmp+w[i]*ksm(X-x[i],M-2)%M)%M;
    			printf("%lld
    ",(tmp*_tmp%M+M)%M);
    		}
    	}
    }
    
    signed main()
    {
    	init();
    	work();
    	return 0;
    }
    
    
  • 相关阅读:
    浅析TCP /UDP/ IP协议
    大小端模式
    小技巧—计算内存
    浅谈启发式合并
    浅谈换根DP
    POJ 3585 Accumulation Degree
    OSGi类加载问题
    Redis缓存集群方案
    Tair分布式缓存
    Tedis:淘宝的Redis的Java客户端开发包
  • 原文地址:https://www.cnblogs.com/With-penguin/p/13510369.html
Copyright © 2011-2022 走看看