多项式算法 学习笔记

NTT

真的学不会,所以直接背代码:

  • 刚开始求一个 \(len\) 的目的,是因为长度必须是 \(2\) 的次幂。
  • 后来求了一个 \(rev\) 数组,背下来就行了。
  • 再后来是把 \(a\)\(b\) 的长度补位到 \(len\)
  • 然后分别给 \(a\)\(b\) 执行 NTT 函数,这个是系数表示法转点值表示法,所以第二项是 \(1\)
  • 然后直接每一位都相乘。
  • 然后把算好的 \(a\) 从点值转化为系数。
  • 最后数组的每个值都需要除以 \(len\),具体原因我也不知道,反正除就行了,除完就是最终答案。
  • 最后一个是把数组中多余的 \(0\) 去除掉,然后返回。
  • NTT 函数直接背就行了。

折叠块会出奇怪的问题,我也不知道咋回事。

#include<bits/stdc++.h>
#define int long long
using namespace std;
auto mread = [](){int x;scanf("%lld", &x);return x;};
const int N = 5e6 + 5, MOD = 998244353, g = 3, gi = 332748118;
int n = mread(), m = mread(), rev[N];
int ksm(int x, int k){
    int ans = 1, now = x;
    while(k){
        if(k & 1)
        ans = ans * now % MOD;
        now = now * now % MOD;
        k >>= 1;
    }
    return ans;
}
struct node{
    vector<int> v;
    void NTT(int n, int type){
        for(int i = 0; i < n; i ++)
        if(i < rev[i])
        swap(v[i], v[rev[i]]);
        for(int i = 1; i < n; i <<= 1){
            int gn = ksm(type ? g : gi, (MOD - 1) / (i << 1));
            for(int j = 0; j < n; j += (i << 1)){
                int g0 = 1;
                for(int k = 0; k < i; k ++, g0 = g0 * gn % MOD){
                    int x = v[j + k], y = g0 * v[i + j + k] % MOD;
                    v[j + k] = (x + y) % MOD;
                    v[i + j + k] = (x - y + MOD) % MOD;
                }
            }
        }
    }
    friend node operator *(node a, node b){
        int len = 1;
        while(len < (a.v.size() + b.v.size()))
        len <<= 1;
        for(int i = 0; i < len; i ++)
        rev[i] = (i & 1) * (len >> 1) + (rev[i >> 1] >> 1);
        while(a.v.size() < len)
        a.v.push_back(0);
        while(b.v.size() < len)
        b.v.push_back(0);
        a.NTT(len, 1);
        b.NTT(len, 1);
        for(int i = 0; i < len; i ++)
        a.v[i] = a.v[i] * b.v[i] % MOD;
        a.NTT(len, 0);
        int inv = ksm(len, MOD - 2);
        for(int i = 0; i < len; i ++)
        a.v[i] = a.v[i] * inv % MOD;
        while(a.v.back() == 0)
        a.v.pop_back();
        return a;
    }
}a, b;
signed main(){

    return 0;
}
posted @ 2024-02-22 22:19  cndark_moon  阅读(31)  评论(0)    收藏  举报