Luogu4191 [CTSC2010] [多項式パフォーマンスの最適化、巡回畳み込み]

説明タイトル:レッツ$ A、Bの$する$ N-1 $度シーク$ A * B ^ C $係数金型の$ N + 1 $、$長$ nの円形畳み込みの多項式です。

データの範囲:$ n個の\の当量5×10 ^ 5、C \の当量10 ^ 9 $、$ 7以下の$ N-素因数は、$ N + 1 $が素数です。


これは巡回畳み込みではなく、ここで、k個の$ = 2の場合にFFT / NTT $ N ^として用いてもよいです。

N- $ $小さな素因数ので、$ N = 2 ^ {K_1} * 3 ^ {K_2} * 5 ^ {K_3} * 7 ^ {k_4} $を設定し、我々は、N- $ $ $ pはパーティションで検討$部品(NTTは、ケースの$ P = 2 $であり、ここで、$ p = 2,3,5,7- $)

$$ F(\ omega_n ^ I)= \ sum_ {i = 0} ^ {P-1} \ omega_n ^ iF_i(\オメガ_ {\ FRAC {N} {P}} ^ I)$$

设$ a_iを= F(x)は[X ^ i]は$

$$ F_R(X)= \ sum_ {I} A_ {IP + R} X ^ I $$

$のレブ$配列は、実際に一緒に入れ、型$ pが$合同です。

NTTの逆変換$ -i $への回数$ I $、私は$ Aに直接書いているコードです。(ここでは逆の順序であること)[1のn-1] $実施リバース

1の#include <ビット/ STDC ++ H>
 2  の#define RINTレジスタINT
 3  使用して 名前空間STDを、
4のtypedef 長い LL。
5  のconst  int型 N = 500003 6  int型N、C、MOD、PRI [N]、TOT、Wnは[N]。
7インラインボイド追加(INT&、int型 B){A + B =。もし(> = MOD)A - = MOD;}
 8インラインINTかすみ(int型int型B)を{
 9      INT RES =1 ;
10      一方、(B){
 11          であれば(B&1)RES =(LL)RES *%のMOD。
12          =(LL)A *%のMOD。
13          B >> = 1 14      }
 15の     リターンRES。
16  }
 17インラインボイドファクター(int型N){
 18      (RINT I = 2 ; iは<= N *; iが++ 19を         場合(!(N%I))PRI [++のTOT = iが、n個/ = I - I。
20      であれば(N> 1)PRI [++のTOT = N。
21  }
 22インラインINT プリミティブ(){
 23      のための(iは= RINT 2 ;; iは++ ){
 24          ブールフラグ= 25          のための(RINTのJ = 1 ; J <= TOT &&フラグ、J ++ 26              であれば(かすみ(I、N / PRI [J])== 1)フラグ= 27          であれば(フラグ)リターンI。
28      }
 29  }
 30  INT B [N]、[N]、TMP [N]。
31インライン無効改訂(INT * A){
 32の     ため(RINT I = TOT、ブロック= N; iは、ブロック/ = PRI [i]は、iが- ){
 33の         ための(RINTのNUM = 0、J = 0 ; J <N ; J + = ブロック)
 34              のための(RINTのK = 0 ; K <PRI [i]は、++ kは35                  のための(RINTさl = 0 ; L <ブロック; L + = PRI [i])と
 36                      TMP [NUM + +] = A [J + K + L]。
37          のために(RINT i = 0 ; iがn <; iは++)A [i]は= TMPを[I]。
38      }
 39  }
 40インラインボイド NTT(INT * A、int型タイプ){
 41      改訂(A)。
42      のために(RINT I = 1、ブロック= 1 ; I <= TOT; iは++ ){
 43          INTミッド=ブロック、WI = Wnは[N /(ブロック* = PRI [I])]。
44          のための(RINTのJ = 0 ; nはJ <; J ++)TMP [J] = 0 ;
45          のための(RINTのJ = 0 ; J <N; J + = ブロック){
 46              INT週= 1 47              のための(RINTのK = 0 ; K <ブロックあり、k ++ ){
48                  のための(RINTのL = Kの%の半ば、W = 1 ; L <ブロック*の週%のW L + =中間、W =(LL)MOD)
 49                      * A wを追加(TMP [J + K]、(LL) [J + 1]%のMOD)。
50                  週=(LL)週*ウィスコンシンの%のMOD。
51              }
 52          }
 53          (RINTのJ = 0 ; J <N; J ++)A [j]は= TMP [j]を。
54      }
 55      であれば(タイプ== - 1 ){
 56          のstd ::逆(A + 1、A + N)。
57          のための RINT I =(0、iがN <; I ++58              A [I] =(LL)A [I] * N%MOD。
59      }
 60  }
 61  INT メイン(){
 62      のscanf(" %D%dの"、&​​N、&C)。MOD = N + 1 63      のために(RINT i = 0 ; iがn <; iは++)のscanf(" %dの"、A + I)。
64      のために(RINT i = 0 ; iがn <; iは++)のscanf(" %dの"、B + I)。
65      因子(N)
66      Wnは[ 0 ] = 1; WN [ 1 ] = (プリミティブ)。
67      のために(RINT I = 2 - [I Wnは[I] =(LL)Wnは; iが<= N I ++)は1 ] * Wnは、[ 1 ]%; MOD
68      NTT(1)。NTT(B、1 );
69      のために(RINT i = 0 ; iがn <; iは++ 70          [I] =(LL)[I] *かすみ(B [i]は、C)%MOD。
71      NTT( - 1 )。
72      のために(RINT i = 0 ; iがn <; I ++ 73          のprintf(" %d個の\ n "、[I])。
74 }
Luogu4191

 

おすすめ

転載: www.cnblogs.com/AThousandMoons/p/10991952.html