HDU 6061

每次NTT都忘记初始化,真的是写一个小时,Debug两个小时- -

/*
HDU 6061 - RXD and functions [ NTT ]  |  2017 Multi-University Training Contest 3
题意:
	给定多项式 F(x) = ∑[0<=i<=n] f(i)*x^i
	求多项式 G(x) = F(x-a)
	n <= 1e5
分析:
	设 G(x) = ∑ g(i)*x^i
	将 F(x-a) 按二项式定理展开后易得:
		g(x) = ∑[x<=y<=n] Comb(y,x) * f(y) * (-a)^(y-x)
	打开组合数,移项:
		g(x)*x! = ∑[x<=y<=n] f(y)*y!  *  (-a)^(y-x) / (y-x)!
	设 g'(x) = g(x)*x!
		p(x) = f(y)*y!
		q(x) = (-a)^x/x!
	则 g'(x) = ∑[x<=y<=n] p(y) * q(y-x)
			 = ∑[1<=y<=n-x] p(y+x) * q(y)
	设 g''(x) = g'(n-x)
	则 g''(x) = ∑[1<=y<=x] p(n-(x-y)) * q(y)
	设 p'(x) = p(n-x)
	则 g''(x) = ∑[1<=y<=x] p'(x-y) * q(y)
	算出这个卷积后回带即可
*/
#include <bits/stdc++.h>
using namespace std;
#define LL long long
const int N = 1e5+5;
const LL MOD = 998244353;
namespace NTT {
    const int G = 3;
    const int NUM = 20;
    LL wn[20];
    LL mul(LL x, LL y) {
        return x*y% MOD;
    }
    LL PowMod(LL a, LL b) {
        LL res = 1;
        a %= MOD;
        while (b) {
            if (b&1) res = mul(res, a);
            a = mul(a, a);
            b >>= 1;
        }
        return res;
    }
    void Init() {

        for (int i = 0; i < NUM; i++)
        {
            int t = 1<<i;
            wn[i] = PowMod(G, (MOD-1)/t);
        }
    }
    void Change(LL a[], int len)
    {
        int i, j, k;
        for (i = 1, j = len/2; i < len-1; i++)
        {
            if (i < j) swap(a[i], a[j]);
            k = len/2;
            while (j >= k) {
                j -= k;
                k /= 2;
            }
            if (j < k) j += k;
        }
    }
    void NTT(LL a[], int len, int on)
    {
        Change(a, len);
        int id = 0;
        for (int h = 2; h <= len; h <<= 1)
        {
            id++;
            for (int j = 0; j < len; j += h)
            {
                LL w = 1;
                for (int k = j; k < j + h/2; k++)
                {
                    LL u = a[k] % MOD;
                    LL t = mul(a[k+h/2], w);
                    a[k] = (u+t) % MOD;
                    a[k+h/2] = ((u-t)% MOD + MOD ) % MOD;
                    w = mul(w, wn[id]);
                }
            }
        }
        if (on == -1) {
            for (int i = 1; i < len/2; i++)
                swap(a[i], a[len-i]);
            LL inv = PowMod(len, MOD-2);
            for (int i = 0; i < len; i++)
                a[i] = mul(a[i], inv);
        }
    }
    void solve(LL a[], int n, LL b[], int m)
    {
        int len = 1;
        while (len < n*2 || len < m*2) len <<= 1;
        for (int i = n; i < len; i++) a[i] = 0;
        for (int i = m; i < len; i++) b[i] = 0;
        NTT(a, len, 1);
        NTT(b, len, 1);
        for (int i = 0; i < len; i++) a[i] = mul(a[i], b[i]);
        NTT(a, len, -1);
    }
}
LL f[N], p[N<<3], q[N<<3];
LL a;
int n, m;
LL F[N], Finv[N], inv[N];
void init(){
    inv[1] = 1;
    for (int i = 2; i < N; i++) {
        inv[i] = (MOD-MOD/i) * inv[MOD%i] % MOD;
    }
    F[0] = Finv[0] = 1;
    for (int i = 1; i < N; i++){
        F[i] = F[i-1] * i % MOD;
        Finv[i] = Finv[i-1] * inv[i] % MOD;
    }
}
void solve()
{
    for (int i = 0; i <= n; i++)
        p[i] = F[i] * f[i] % MOD;//p(x)
    q[0] = 1;
    for (int i = 1; i <= n; i++)
        q[i] = q[i-1] * (MOD-a) % MOD * inv[i] % MOD;//q(x)
    for (int i = 0; i <= n/2; i++)
        swap(p[i], p[n-i]);//p'(x)
    NTT::solve(p, n+1, q, n+1);//g''(x)
    for (int i = 0; i <= n/2; i++)
        swap(p[i], p[n-i]);//g'(x)
    for (int i = 0; i <= n; i++)
        p[i] = p[i] * Finv[i] % MOD;//g(x)
}
int main()
{
    init();
    NTT::Init();
    while (~scanf("%d", &n))
    {
        for (int i = 0; i <= n; i++) scanf("%lld", &f[i]);
        scanf("%d", &m);
        a = 0;
        for (int i = 1; i <= m; i++)
        {
            LL x; scanf("%lld", &x);
            a = (a+x) % MOD;
        }
        solve();
        for (int i = 0; i <= n; i++) printf("%lld ", p[i]);
        puts("");
    }
}

  

我自倾杯,君且随意
原文地址:https://www.cnblogs.com/nicetomeetu/p/7290607.html