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("");
        }
    }
    

      

    我自倾杯,君且随意
  • 相关阅读:
    LeetCode Array Easy 414. Third Maximum Number
    LeetCode Linked List Medium 2. Add Two Numbers
    LeetCode Array Easy 283. Move Zeroes
    LeetCode Array Easy 268. Missing Number
    LeetCode Array Easy 219. Contains Duplicate II
    LeetCode Array Easy 217. Contains Duplicate
    LeetCode Array Easy 189. Rotate Array
    LeetCode Array Easy169. Majority Element
    LeetCode Array Medium 11. Container With Most Water
    LeetCode Array Easy 167. Two Sum II
  • 原文地址:https://www.cnblogs.com/nicetomeetu/p/7290607.html
Copyright © 2011-2022 走看看