【BZOJ3453】XLkxc

http://192.168.102.138/JudgeOnline/problem.php?id=3170

知识点:1.拉格朗日插值(多特殊函数相加)

    2.这个式子看似非常复杂,然而只要明白这个式子拆开是一个只有一个变量的多项式就OK,不管这个多项式有多复杂,但只要知道k+4个点的点值,就可以使用插值给弄出来

    3.这题要求的式子其实拆开后与a和d并无关系,只是一个有k+4项的多项式,所以我们插值取的x与a,d并无关系

#include <bits/stdc++.h>
#define p 1234567891
#define N 157
#define ll long long
using namespace std;
ll a,n,d,m,k;
ll s1[N],s2[N];
ll g[N],f[N],inv[N<<1];
int read()
{
    int tt;
    scanf("%d",&tt);
    return tt;
}
ll fast_pow(ll a,ll b)
{
    ll ans = 1;
    while(b)
    {
        if (b & 1) 
            (ans *= a) %= p;
        (a *= a) %= p;
        b >>= 1;
    }
    return ans;
}
inline ll Lagrange(ll *a,int n,ll pos)
{
    if (pos <= n) return a[pos];
    ll ans = 0;
    for (int i = 1;i <= n;i++)
    {
        ll s1 = 1,s2 = 1;
        for (int j = 1;j <= n;j++)
            if (i != j)
            {
                (s1 *= (pos - j)) %= p;
                (s2 *= (i - j)) %= p;
            }
        (ans += a[i] * s1 % p  * fast_pow(s2,p - 2)) %= p;
}
    return ans;
}
int main()
{
    int T = read();
    while(T--)
    {
        k = read(),a = read(),n = read(),d = read();
        for (int i = 1;i <= k + 3;i++) g[i] = fast_pow(i,k);
        for (int i = 2;i <= k + 3;i++) (g[i] += g[i - 1]) %= p;
        for (int i  = 2; i <= k + 3;i++) (g[i] += g[i - 1]) %= p;
        f[0] = Lagrange(g,k+3,a);
        for (int i = 1;i <= k + 5;i++) f[i] = Lagrange(g,k + 3,(i * d + a) % p),(f[i] += f[i - 1]) %= p;
        printf("%lld\n",(Lagrange(f,k + 5,n)  + p) % p);
    }
    return 0;
}

 

posted @ 2020-09-09 12:46  ywwywwyww  阅读(169)  评论(0编辑  收藏  举报