前言
51nod1258真是道好题。。。
一道题,学会了3个东西:伯努利数,自然数幂和,MTT…
前置科技(其实学MTT的人估计都会。。。)
CRT(中国剩余定理)
NTT
NTT算法的局限
众所周知,NTT是通过原根的性质来进行快速傅里叶变化
不过,同时也对其模数做出了要求,对于一个模数M,若 φ ( M ) \varphi(M) φ(M)中,2的次数较少(小于要转的序列长度)就不可做了
所以,也因此衍生出了“NTT模数”,即 φ ( M ) \varphi(M) φ(M)中2的次数较多的模数。
常见的有: 998244353 = 2 23 ∗ 119 + 1 998244353=2^{23}*119+1 998244353=223∗119+1, 1004535809 = 2 21 ∗ 479 + 1 1004535809=2^{21}*479+1 1004535809=221∗479+1, 469762049 = 2 26 ∗ 7 + 1 469762049=2^{26}*7+1 469762049=226∗7+1
(请至少记住这三个模数。。。因为后面要用。。。)
但是,有些无良的出题人,由于懒得想好题,于是就把一些比较简单的多项式题目中的模数换掉(如换成1e9+7),以此来强迫选手要么写拆系数FFT,要么写MTT…
拆系数FFT容易卡精然后WA
MTT容易卡常然后T
To wa or to tle,that’s a question.
MTT
MTT说白了就是用三个NTT模数分别算出一个解,然后再用CRT合并出原来的解
为什么要用三个模数呢。。这是因为,根据CRT的使用条件,如果真正的答案比你的模数之积大,那是得不到唯一解的。所以要求你的模数之积超过真正的解得值域上界。然而一般来说,用MTT都是因为模数是1e9+7,然后 ( 1 e 9 + 7 ) 2 ∗ N ( 1 0 5 左 右 ) ≈ 1 0 23 (1e9+7)^2*N(10^5左右)≈10^{23} (1e9+7)2∗N(105左右)≈1023,所以为了超过这个值,一般都用3个模数。
不过很多情况下这是会爆long long的(不爆long long还不如直接去FFT然后强转。。。)
所以,不能直接利用CRT。
但可以通过一些技巧,算出真正的解
已知
a n s ≡ c 0 ( m o d m 0 ) ans\equiv c_0(mod \ m_0) ans≡c0(mod m0)
a n s ≡ c 1 ( m o d m 1 ) ans\equiv c_1(mod \ m_1) ans≡c1(mod m1)
a n s ≡ c 2 ( m o d m 2 ) ans\equiv c_2(mod \ m_2) ans≡c2(mod m2)
首先利用CRT合并前两项
记 I m 0 = m 0 − 1 ( m o d