• 模板


    先看看。

    通常模数常见的有998244353,1004535809,469762049,这几个的原根都是3。
    所求的项数还不能超过2的23次方(因为998244353的分解)。

    感觉没啥用。

    #include <cstdio>
    #include <cstring>
    
    template <class T>
    inline void swap(T &a, T &b)
    {
        T c;
        c = a;
        a = b;
        b = c;
    }
    
    const int siz = 500005;
    
    const int P = 998244353, G = 3;
    
    inline int pow(int a, int b)
    {
        int r = 1;
        
        while (b)
        {
            if (b & 1)
                r = 1LL * r * a % P;
            
            b >>= 1, a = 1LL * a * a % P;
        }
        
        return r;
    }
    
    inline void calculateNTT(int *s, int n, int f)
    {
        {
            int cnt = 0;
            
            static int rev[siz];
            
            while (n >> cnt)++cnt; --cnt;
            
            memset(rev, 0, sizeof rev);
            
            for (int i = 0; i < n; ++i)
            {
                rev[i] |= rev[i >> 1] >> 1;
                rev[i] |= (i & 1) << (cnt - 1);
            }
            
            for (int i = 0; i < n; ++i)if (i < rev[i])swap(s[i], s[rev[i]]);
        }
        
        {
            for (int i = 1; i < n; i <<= 1)
            {
                int wn = pow(G, (P - 1) / (i * 2));
                
                if (f == -1)wn = pow(wn, P - 2);
                
                for (int j = 0; j < n; j += (i << 1))
                {
                    int wk = 1;
                    
                    for (int k = 0; k < i; ++k, wk = 1LL * wk * wn % P)
                    {
                        int x = s[j + k];
                        int y = 1LL * s[i + j + k] * wk % P;
                        
                        s[j + k] = x + y;
                        s[i + j + k] = x - y;
                        
                        s[j + k] = (s[j + k] % P + P) % P;
                        s[i + j + k] = (s[i + j + k] % P + P) % P;
                    }
                }
            }
        }
        
        {
            if (f == -1)
            {
                int inv = pow(n, P - 2);
                
                for (int i = 0; i < n; ++i)
                    s[i] = 1LL * s[i] * inv % P;
            }
        }
    }
    
    signed main(void)
    {
        static char sa[siz]; 
        static char sb[siz];
        
        scanf("%s", sa);
        scanf("%s", sb);
        
        static int la, a[siz];
        static int lb, b[siz];
        
        la = strlen(sa);
        lb = strlen(sb);
        
        for (int i = 0; i < la; ++i)a[i] = sa[la - i - 1] - '0';
        for (int i = 0; i < lb; ++i)b[i] = sb[lb - i - 1] - '0';
        
        int len; for (len = 1; len < la || len < lb; len <<= 1);
        
        calculateNTT(a, len << 1, +1);
        calculateNTT(b, len << 1, +1);
        
        
        for (int i = 0; i < len << 1; ++i)a[i] = 1LL * a[i] * b[i] % P;
        
        calculateNTT(a, len << 1, -1); 
        
        for (int i = 0; i < len << 1; ++i)a[i + 1] += a[i] / 10, a[i] = a[i] % 10;
        
        len <<= 1; while (!a[len])--len;
        
        for (int i = len; ~i; --i)printf("%d", a[i]); puts("");
    }

    快速傅里叶变换FFT

  • 相关阅读:
    DataGridView在vb.net中的操作技巧
    0、(空字串)、Null、Empty、与Nothing的区别
    System.Timers.Timer与System.Windows.Forms.Timer 区别
    C#判断常见类型格式是否正确的类
    C#对系统注册表操作的类
    Socket基础知识分享
    怎样才能充分利用SQL索引
    通过建立Socket连接来快速判断数据库连接是否正确
    C#中各种数据类型转换的方法的类
    VB.Net C#代码转换工具
  • 原文地址:https://www.cnblogs.com/Yinku/p/10533180.html
Copyright © 2020-2023  润新知