zoukankan      html  css  js  c++  java
  • HDU6061 RXD and functions【NTT】

    (RXD and functions)

    Problem Description
    RXD has a polynomial function (f(x)), (f(x)=sum ^{n}_{i=0}c_ix_i)
    RXD has a transformation of function (Tr(f,a)), it returns another function g, which has a property that (g(x)=f(x−a)).
    Given (a_1,a_2,a_3,…,a_m), RXD generates a polynomial function sequence (g_i), in which (g_0=f) and (g_i=Tr(g_{i−1},a_i))
    RXD wants you to find (g_m), in the form of (sum ^{m}_{i=0}b_ix_i)
    You need to output bi module (998244353.)
    (n≤10^5)

    Input
    There are several test cases, please keep reading until EOF.
    For each test case, the first line consists of (1) integer (n), which means (deg F).
    The next line consists of (n+1) intergers (c_i)(0 le ci<998244353), which means the coefficient of the polynomial.
    The next line contains an integer (m), which means the length of (a).
    The next line contains (m) integers, the (i) - th integer is (a_i).
    There are (11) test cases.
    (0le ai<998244353)
    (sum mle10^5)

    Output
    For each test case, output an polynomial with degree n, which means the answer.

    Sample Input
    2
    0 0 1
    1
    1

    Sample Output
    1 998244351 1
    Hint
    ((x - 1) ^ 2 = x^2 - 2x + 1)

    题解:
    显然最终操作完的式子为(sum_{i=0}^{n}c_i(x-sum_{i-1}^{m}a_i)^i)
    现在我们记((-sum_{i=1}^{m}a_i)\%MOD=a)
    然后变成这样:
    (sum_{i=0}^{n}c_i(x-a)^i)
    接下来我们对式子进行二项式展开:
    (sum_{i=0}^{n}sum_{j=i}^{n}C(j,j-i)c_jcdot a^{j-i}cdot x^i)
    (j=j-i)替换(j)
    (sum_{i=0}^{n}sum_{j=0}^{n-i}C(j+i,j)cdot c_{j+i}cdot a^jcdot x^j)
    把组合数展开:
    (sum_{i=0}^{n}sum_{j=0}^{n-i}frac{(i+j)!}{i!cdot j!}c_{i+j}cdot a^jcdot x^j)
    整理一下,把和内层求和无关的提到外面来得到:
    (sum_{i=0}^{n}frac{x^i}{i!}sum_{j=0}^{n-i}c_{i+j}cdot (i+j)!cdotfrac{a^j}{j!})
    现在我们先怎么转化里面的式子,使之变成卷积的形式:
    (sum_{j=0}^{n-i}c_{i+j}cdot (i+j)!cdotfrac{a^j}{j!})
    (j+k=n-i)来做替换:
    (Rightarrow sum_{j+k=n-i} c_{n-k}cdot (n-k)!cdot frac{a^j}{j!})
    发现这个式子就是卷积的形式了
    (A[n]=sum c_{n-i}cdot (n-i)!)
    (B[n]=sum frac{a^i}{i!})

    (NTT)来搞即可

    //#pragma GCC optimize("O3")
    //#pragma comment(linker, "/STACK:1024000000,1024000000")
    #include<bits/stdc++.h>
    using namespace std;
    function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
    const int MAXN = 1e6+7;
    using LL = int_fast64_t;
    const LL MOD = 998244353;
    const LL g = 3;
    int n,limit,m,l,r[MAXN];
    LL fact[MAXN],rfact[MAXN],c[MAXN],A[MAXN],B[MAXN];
    LL qpow(LL a, LL b){
        LL ret = 1;
        while(b){
            if(b&1) ret = ret * a % MOD;
            b >>= 1;
            a = a * a % MOD;
        }
        return ret;
    }
    LL inv(LL x){ return qpow(x,MOD-2); }
    void NTT(LL arr[], int rev){
        for(int i = 0; i < limit; i++) if(i<r[i]) swap(arr[i],arr[r[i]]);
        for(int len = 1; len < limit; len <<= 1){
            LL wn = qpow(g,(MOD-1)/(len<<1));
            if(rev==-1) wn = inv(wn);
            for(int R = 0; R < limit; R += (len<<1)){
                LL w = 1;
                for(int i = R; i < R + len; i++){
                    LL x = arr[i];
                    LL y = w * arr[i+len] % MOD;
                    arr[i] = (x+y)%MOD;
                    arr[i+len] = (x-y+MOD)%MOD;
                    w = w * wn % MOD;
                }
            } 
        }
    }
    void solve(){
        LL a = 0;
        for(int i = 0; i <= n; i++) scanf("%I64d",&c[i]);
        scanf("%d",&m);
        for(int i = 1; i <= m; i++){
            int x; scanf("%d",&x);
            a -= x;
            if(a<0) a += MOD;
        }
        limit = 1, l = 0;
        while(limit<=(n<<1)) limit <<= 1, l++;
        for(int i = 0; i < limit; i++) r[i] = ((r[i>>1]>>1) | ((i&1)<<(l-1)));
        LL powa = 1;
        for(int i = 0; i < limit; i++){
            if(i<=n){
                A[i] = fact[n-i] * c[n-i] % MOD;
                B[i] = powa * rfact[i] %MOD;
                powa = powa * a % MOD;
            }
            else A[i] = B[i] = 0;
        }
        NTT(A,1); NTT(B,1);
        for(int i = 0; i < limit; i++) A[i] = A[i] * B[i] % MOD;
        NTT(A,-1);
        for(int i = 0; i < limit; i++) A[i] = A[i] * inv(limit) % MOD;
        for(int i = 0; i <= n; i++) printf("%I64d ",A[n-i]*rfact[i]%MOD); puts("");
    }
    int main(){
        fact[0] = 1; for(int i = 1; i < MAXN; i++) fact[i] = i * fact[i-1] % MOD;
        rfact[MAXN-1] = inv(fact[MAXN-1]);
        for(int i = MAXN - 2; i >= 0; i--) rfact[i] = rfact[i+1] * (i+1) % MOD;
        while(scanf("%d",&n)!=EOF) solve();
        return 0;
    }
    
  • 相关阅读:
    asp.net Ajax调用Aspx后台方法
    JS 通过字符串取得对应对象
    nginx js、css、图片 及 一些静态文件中出现 http://upstreamname:port 导致部分网页样式显示不正常
    jexus手动跨域设置
    HTTP Error 400. The request hostname is invalid
    at MySql.Data.MySqlClient.MySqlStream.ReadPacket 或 FUNCTION account.AddMinutes does not exist
    sql xml 入门
    Jexus .Net at System.Net.Sockets.Socket.Connect (System.Net.IPAddress[] addresses, System.Int32 port)
    关于SQL SERVER中的FLOAT转换为VARCHAR
    JS倒计时
  • 原文地址:https://www.cnblogs.com/kikokiko/p/12599137.html
Copyright © 2011-2022 走看看