1+ /**
2+ * Author: chilli, Andrew He, Adamant
3+ * Date: 2019-04-27
4+ * Description: A FFT based Polynomial class.
5+ */
6+ #pragma once
7+
8+ #include "../number-theory/ModularArithmetic.h"
9+ #include "FastFourierTransform.h"
10+ #include "FastFourierTransformMod.h"
11+ // #include "NumberTheoreticTransform.h"
12+
13+ typedef Mod num ;
14+ typedef vector < num > poly ;
15+ vector < Mod > conv (vector < Mod > a , vector < Mod > b ) {
16+ auto res = convMod < mod > (vl (all (a )), vl (all (b )));
17+ // auto res = conv(vl(all(a)), vl(all(b)));
18+ return vector < Mod > (all (res ));
19+ }
20+ poly & operator += (poly & a , const poly & b ) {
21+ a .resize (max (sz (a ), sz (b )));
22+ rep (i , 0 , sz (b )) a [i ] = a [i ] + b [i ];
23+ return a ;
24+ }
25+ poly & operator -= (poly & a , const poly & b ) {
26+ a .resize (max (sz (a ), sz (b )));
27+ rep (i , 0 , sz (b )) a [i ] = a [i ] - b [i ];
28+ return a ;
29+ }
30+
31+ poly & operator *=(poly & a , const poly & b ) {
32+ if (sz (a ) + sz (b ) < 100 ){
33+ poly res (sz (a ) + sz (b ) - 1 );
34+ rep (i ,0 ,sz (a )) rep (j ,0 ,sz (b ))
35+ res [i + j ] = (res [i + j ] + a [i ] * b [j ]);
36+ return (a = res );
37+ }
38+ return a = conv (a , b );
39+ }
40+ poly operator * (poly a , const num b ) {
41+ poly c = a ;
42+ trav (i , c ) i = i * b ;
43+ return c ;
44+ }
45+ #define OP (o , oe ) \
46+ poly operator o(poly a, poly b) { \
47+ poly c = a; \
48+ return c oe b; \
49+ }
50+ OP (* , *=) OP (+ , += ) OP (- , -= );
51+ poly modK (poly a , int k ) { return {a .begin (), a .begin () + min (k , sz (a ))}; }
52+ poly inverse (poly A ) {
53+ poly B = poly ({num (1 ) / A [0 ]});
54+ while (sz (B ) < sz (A ))
55+ B = modK (B * (poly ({num (2 )}) - modK (A , 2 * sz (B )) * B ), 2 * sz (B ));
56+ return modK (B , sz (A ));
57+ }
0 commit comments