zoukankan      html  css  js  c++  java
  • 2019ICPC邀请赛南昌B Polynomial 拉格朗日插值

    让你求f(L)到f(R)的和。

    我们考虑前缀和,F(x)必定是比f(x)次数高1的多项式,所以我们先插值插出f(n+1)。然后求出n+1个前缀和,插值出前缀和即可。

     1 #include <cstdio>
     2 using namespace std;
     3 typedef long long ll;
     4 const int mo = 9999991;
     5 int n,m,T;
     6 ll y1[1100],y2[1100],pre[1100],suf[1100],inv[1100];
     7 ll fpow(ll x,int k)
     8 {
     9     if (k == 0)
    10         return 1;
    11     ll t = fpow(x,k >> 1);
    12     if (k & 1)
    13         return t * t % mo * x % mo;
    14     return t * t % mo; 
    15 }
    16 ll calc(ll y[],int n,int x)
    17 {
    18     if (x <= n)
    19         return y[x];
    20     pre[0] = x;
    21     suf[n] = x - n;
    22     for (int i = 1;i <= n;i++)
    23         pre[i] = pre[i - 1] * (x - i) % mo;
    24     for (int i = n - 1;i >= 0;i--)
    25         suf[i] = suf[i + 1] * (x - i) % mo;
    26     ll ans = 0; 
    27     for (int i = 0;i <= n;i++)
    28     {
    29         ll tans = (n - i) & 1 ? -y[i] : y[i];
    30         if (i >= 1)
    31             tans = (tans * pre[i - 1] % mo + mo) % mo;
    32         if (i <= n - 1)
    33             tans = (tans * suf[i + 1] % mo + mo) % mo;
    34         tans = (tans * inv[n - i] % mo * inv[i] % mo + mo) % mo;
    35         ans = (ans + tans) % mo;
    36     }
    37     return ans;
    38 }
    39 int main()
    40 {
    41     ll t = 1;
    42     for (int i = 1;i <= 1000;i++)
    43         t = t * i % mo;
    44     inv[1000] = fpow(t,mo - 2);
    45     for (int i = 999;i >= 0;i--)
    46         inv[i] = inv[i + 1] * (i + 1) % mo;
    47     for (scanf("%d",&T);T;T--)
    48     {
    49         scanf("%d%d",&n,&m);
    50         for (int i = 0;i <= n;i++)
    51             scanf("%lld",&y1[i]);
    52         y1[n + 1] = calc(y1,n,n + 1);
    53         for (int i = 1;i <= n + 1;i++)
    54             y2[i] = y2[i - 1] + y1[i]; 
    55         int tl,tr;
    56         for (int i = 1;i <= m;i++)
    57         {
    58             scanf("%d%d",&tl,&tr);
    59             printf("%lld
    ",((calc(y2,n + 1,tr) - calc(y2,n + 1,tl - 1)) % mo + mo) % mo);
    60         }
    61     }
    62     return 0;
    63 }
  • 相关阅读:
    Linux进程间通信—消息队列
    Linux进程间通信—信号
    Linux进程间通信—信号量
    Linux进程间通信—管道
    Linux进程间通信:管道,信号量,消息队列,信号,共享内存,套接字
    安全文件传输系统
    嵌入式mp3播放器
    用C语言实现面向对象的开发
    Haskell 差点儿无痛苦上手指南
    Oracle EBS 入门
  • 原文地址:https://www.cnblogs.com/iat14/p/12449392.html
Copyright © 2011-2022 走看看