5
5
*/
6
6
#pragma once
7
7
8
+ #include "../number-theory/ModularArithmetic.h"
8
9
#include "FastFourierTransform.h"
10
+ #include "FastFourierTransformMod.h"
9
11
10
- typedef double num ;
12
+ typedef Mod num ;
11
13
typedef vector < num > poly ;
14
+ vector < Mod > conv (vector < Mod > a , vector < Mod > b ) {
15
+ auto res = convMod < mod > (vl (all (a )), vl (all (b )));
16
+ return vector < Mod > (all (res ));
17
+ }
12
18
poly & operator += (poly & a , poly & b ) {
13
19
a .resize (max (sz (a ), sz (b )));
14
- rep (i ,0 ,sz (b )) a [i ] += b [i ];
20
+ rep (i ,0 ,sz (b )) a [i ] = a [ i ] + b [i ];
15
21
return a ;
16
22
}
17
23
poly & operator -= (poly & a , poly b ) {
18
24
a .resize (max (sz (a ), sz (b )));
19
- rep (i ,0 ,sz (b )) a [i ] -= b [i ];
25
+ rep (i ,0 ,sz (b )) a [i ] = a [ i ] - b [i ];
20
26
return a ;
21
27
}
22
28
poly & operator *=(poly & a , poly & b ) { return a = conv (a , b ); }
@@ -26,3 +32,44 @@ poly &operator*=(poly &a, poly &b) { return a = conv(a, b); }
26
32
return c oe b; \
27
33
}
28
34
OP (* , *=) OP (+ , += ) OP (- , -= );
35
+ poly modK (poly a , int k ) { return {a .begin (), a .begin () + min (k , sz (a ))}; }
36
+ poly inverse (poly A ) {
37
+ poly B = poly ({num (1 ) / A [0 ]});
38
+ while (sz (B ) < sz (A ))
39
+ B = modK (B * (poly ({num (2 )}) - A * B ), 2 * sz (B ));
40
+ return modK (B , sz (A ));
41
+ }
42
+ poly & operator /= (poly & a , poly & b ) {
43
+ if (sz (a ) < sz (b ))
44
+ return a = {};
45
+ int s = sz (a ) - sz (b ) + 1 ;
46
+ reverse (all (a )), reverse (all (b ));
47
+ a .resize (s ), b .resize (s );
48
+ a = a * inverse (b );
49
+ a .resize (s ), reverse (all (a ));
50
+ return a ;
51
+ }
52
+ OP (/, /=)
53
+ poly & operator %=(poly & a , poly & b ) {
54
+ if (sz (a ) < sz (b ))
55
+ return a ;
56
+ poly c = (a / b ) * b ;
57
+ a .resize (sz (b ) - 1 );
58
+ rep (i , 0 , sz (a )) a [i ] = a [i ] - c [i ];
59
+ return a ;
60
+ }
61
+ OP (%, %=)
62
+ poly deriv (poly a ) {
63
+ if (a .empty ())
64
+ return {};
65
+ poly b (sz (a ) - 1 );
66
+ rep (i , 1 , sz (a )) b [i - 1 ] = a [i ] * num (i );
67
+ return b ;
68
+ }
69
+ poly integr (poly a ) {
70
+ if (a .empty ())
71
+ return {};
72
+ poly b (sz (a ) + 1 );
73
+ rep (i , 0 , sz (a ) + 1 ) b [i + 1 ] = a [i ] / num (i + 1 );
74
+ return b ;
75
+ }
0 commit comments