zoukankan      html  css  js  c++  java
  • NTT板子 -- from ACdreamer -- test by HDU6061

    NTT板子

    #include <iostream>
    #include <string.h>
    #include <stdio.h>
    
    using namespace std;
    const int MAXN = 400040;
    typedef long long LL;
    
    const int N = 100005;
    const int P = 998244353;
    const LL MOD = 998244353;
    const int G = 3;
    const int NUM = 25;
    LL x1[MAXN];
    LL x2[MAXN];
    LL c[MAXN/4];
    LL ans[MAXN/4];
    LL  wn[NUM];
    
    LL quick_mod(LL a, LL b, LL m)
    {
        LL ans = 1;
        a %= m;
        while(b)
        {
            if(b & 1)
            {
                ans = ans * a % m;
                b--;
            }
            b >>= 1;
            a = a * a % m;
        }
        return ans;
    }
    
    void GetWn()
    {
        for(int i=0; i<NUM; i++)
        {
            int t = 1 << i;
            wn[i] = quick_mod(G, (P - 1) / t, P);
        }
    }
    void Rader(LL a[], int len)
    {
        int j = len >> 1;
        for(int i=1; i<len-1; i++)
        {
            if(i < j) swap(a[i], a[j]);
            int k = len >> 1;
            while(j >= k)
            {
                j -= k;
                k >>= 1;
            }
            if(j < k) j += k;
        }
    }
    
    void NTT(LL a[], int len, int on)
    {
        Rader(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] % P;
                    LL t = w * (a[k + h / 2] % P) % P;
                    a[k] = (u + t) % P;
                    a[k + h / 2] = ((u - t) % P + P) % P;
                    w = w * wn[id] % P;
                }
            }
        }
        if(on == -1)
        {
            for(int i = 1; i < len / 2; i++)
                swap(a[i], a[len - i]);
            LL Inv = quick_mod(len, P - 2, P);
            for(int i = 0; i < len; i++)
                a[i] = a[i] % P * Inv % P;
        }
    }
    
    void Conv(LL a[], LL b[], int n)
    {
        NTT(a, n, 1);
        NTT(b, n, 1);
        for(int i = 0; i < n; i++)
            a[i] = a[i] * b[i] % P;
        NTT(a, n, -1);
    }
    const int tN = 800000 + 5;
    long long F[tN], Finv[tN], inv[tN];//Fê&#199;&#189;×3&#203;£&#172;Finvê&#199;&#196;&#230;&#212;aμ&#196;&#189;×3&#203;
    void init(){
        inv[1] = 1;
        for(long long  i = 2; i < tN; i ++){
            inv[i] = (MOD - MOD / i) * 1ll * inv[MOD % i] % MOD;
        }
        F[0] = Finv[0] = 1;
        for(long long i = 1; i < tN; i ++){
            F[i] = F[i-1] * 1ll * i % MOD;
            Finv[i] = Finv[i-1] * 1ll * inv[i] % MOD;
        }
    }
    int main()
    {
        GetWn();
        init();
        int n,m;
        while (~scanf("%d",&n)){
            for (int i = 0; i<=n; i++){
                scanf("%I64d",&c[i]);
            }
            scanf("%d",&m);
            long long suma = 0;
            for (int i = 1;i<=m;i++){
                long long a;
                scanf("%I64d",&a);
                suma = (suma - a+MOD) % MOD;
            }
    
            int len1 = n+1;
            int len = 1;
            while ( len < 2*len1 ) len <<= 1;
    
            for (int i = 0; i<len1 ; i++)
                x1[i] = c[n-i]*F[n-i]%MOD;
            for (int i = len1 ; i < len ;i++)
                x1[i] = 0;
            long long po = 1;
            for (int i = 0; i<len1 ; i++){
                x2[i] = po*Finv[i]%MOD;
                po = ((po*suma) % MOD + MOD) % MOD;
            }
            for (int i = len1 ; i < len ;i++)
                x2[i] = 0;
            Conv(x1, x2, len);
    
            for (int i = 0 ; i<=n ; i++)
                ans[n-i] = (long long) (x1[i] + 0.5 ) % MOD;
            if (suma!=0)
            for (int i = 0;i<=n; i++)
                printf("%I64d ",(((ans[i]%MOD)*Finv[i])%MOD+MOD)%MOD);
            else
            for (int i = 0;i<=n; i++)
                printf("%I64d ",c[i]%MOD);
            puts("");
        }
        return 0;
    }
  • 相关阅读:
    语法上的小trick
    [算法模版]斜率优化
    CF886E Maximum Element
    【hdu 1576】A/B(数论--拓展欧几里德 求逆元 模版题)
    【poj 3090】Visible Lattice Points(数论--欧拉函数 找规律求前缀和)
    【poj 2478】Farey Sequence(数论--欧拉函数 找规律求前缀和)
    【poj 1284】Primitive Roots(数论--欧拉函数 求原根个数){费马小定理、欧拉定理}
    【poj 2407】Relatives(数论--欧拉函数 模版题)
    【bzoj 2038】 [2009国家集训队]小Z的袜子(算法效率--莫队分块算法 模版题)
    【uva 1312】Cricket Field(算法效率--技巧枚举)
  • 原文地址:https://www.cnblogs.com/HITLJR/p/7418372.html
Copyright © 2011-2022 走看看