• loj 165


    题目描述
    这是一道模板题。

    维护一个点集 S,初始时点集为空集。下面依次进行 n 个操作,操作有两种:

    1 x y:向点集中添加点((x,y))。保证点集中 x 互不相同。
    2 k:输出 (f(k) mod 998244353) 的值,其中 (f(x)) 是一个次数不超过 (|s|-1) 次的函数,且经过 s 中所有的点。
    输入格式
    第一行,一个整数 n,表示操作个数。

    接下来 n 行,每行 2 或 3 个整数,描述操作。

    数据保证第一个操作必定为 1 类型操作。

    输出格式
    多行,第 i 行,一个整数,表示对第 i 个 2 类型操作要求计算的 (f(k) mod 998244353) 的值。

    样例
    输入
    6
    1 2 3
    2 5
    1 4 7
    2 5
    1 1 4
    2 5
    输出
    3
    9
    12

    数据范围与提示
    对于 (100 \%) 的数据,$ 1<=n<=3000,1<=x,y,k<998244353$,所有x 互不相同。

    数据有一定梯度。


    据说叫做重心拉格朗日差值
    通过对原公式进行变形,使得拉格朗日插值法能够进行增加点和随时计算值。

    [y=sum_{i=1}^{n}y_iprod_{j=1,j eq i}^{n}(x-x_j)/(x_i-x_j) ]

    [y=sum_{i=1}^{n}y_ifrac{prod_{j=1,j eq i}^{n}(x-x_j)}{prod_{j=1,j eq i}^{n}(x_i-x_j)} ]

    [y=sum_{i=1}^{n}y_ifrac{prod_{j=1}^{n}(x-x_j)}{(x-x_i)prod_{j=1,j eq i}^{n}(x_i-x_j)} ]

    [y=prod_{j=1}^{n}(x-x_j)sum_{i=1}^{n}frac{y_i}{(x-x_i)prod_{j=1,j eq i}^{n}(x_i-x_j)} ]

    这里面,(prod_{j=1}^{n}(x-x_j))部分每次询问时可以(O(n))得到。
    (y_i)(x-x_i)可以(O(1))得到
    (prod_{j=1,j eq i}^{n}(x_i-x_j))则需要一个数组来进行存储,每次增加点都要(O(n))维护(代码中lc[])。


    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=3010;
    const int mod=998244353;
    typedef long long ll;
    ll lc[maxn],x[maxn],y[maxn];
    int nn,n;
    ll qpow(int x,int y)
    {
    	if(y==0)return 1;
    	ll tp=qpow(x,y/2);
    	tp=tp*tp%mod;
    	if(y&1)tp=tp*x%mod;
    	return tp;
    }
    int main()
    {
    	scanf("%d",&nn);
    	while(nn--)
    	{
    		int op,a,b;
    		scanf("%d",&op);
    		if(op==1)
    		{
    			scanf("%d%d",&a,&b);
    			++n;
    			y[n]=b;x[n]=a;
    			lc[n]=1;
    			for(int i=1;i<n;++i)lc[i]=lc[i]*(x[i]-x[n])%mod;
    			for(int i=1;i<n;++i)lc[n]=lc[n]*(x[n]-x[i])%mod;
    		}
    		else 
    		{
    			scanf("%d",&a);
    			bool fd=0;
    			for(int i=1;i<=n;++i)
    				if(x[i]==a)
    				{
    					printf("%d
    ",y[i]);
    					fd=1;
    				}
    			if(fd==1)continue;
    			ll tq=1;
    			for(int i=1;i<=n;++i)tq=tq*(a-x[i])%mod;
    			ll he=0;
    			for(int i=1;i<=n;++i)he=(he+y[i]*qpow(lc[i],mod-2)%mod*qpow(a-x[i],mod-2)%mod)%mod;
    			printf("%lld
    ",(tq*he%mod+mod)%mod);
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    【转】c语言中的#号和##号的作用
    stm32 HAL库编程驱动控制文件<stm32f1xx_hal_conf.h>的使能方法
    rt-thread是如何做到通过menuconfig配置将相应文件加入工程和从工程中除去
    rt-thread 学习路线
    stm32使用rt-thread在文件《stm32f1xx_hal.h》中头文件包含顺序引出的错误
    rt-thread之stm32系列BSP制作方法
    使用rt-thread中BSP-stm32 ENV构建工具报错
    rt-thread中动态内存分配之小内存管理模块方法的一点理解
    内存对齐
    rt-thread中线程内置定时器的作用 ---
  • 原文地址:https://www.cnblogs.com/gryzy/p/15004165.html
Copyright © 2020-2023  润新知