zoukankan      html  css  js  c++  java
  • 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("");
        }
    }
    

      

    我自倾杯,君且随意
  • 相关阅读:
    Servlet_note
    J2SE学习历程
    ASP.NET Core搭建多层网站架构【0-前言】
    使用oh-my-posh美化powershell
    Linux使用整理
    Ubuntu18.04国内源安装MySQL8.0
    Visual Studio Code 个人配置备份
    ASP.NET Core搭建多层网站架构【15-扩展之使用Obfuscar混淆加密保护代码】
    ASP.NET Core搭建多层网站架构【14-扩展之部署到IIS】
    ASP.NET Core搭建多层网站架构【13-扩展之支持全球化和本地化多语言】
  • 原文地址:https://www.cnblogs.com/nicetomeetu/p/7290607.html
Copyright © 2011-2022 走看看