@@ -12,6 +12,16 @@ typedef long long ll;
12
12
typedef pair<int , int > pii;
13
13
typedef vector<int > vi;
14
14
15
+ struct timeit {
16
+ decltype (chrono::high_resolution_clock::now()) begin;
17
+ const string label;
18
+ timeit (string label = " ???" ) : label(label) { begin = chrono::high_resolution_clock::now (); }
19
+ ~timeit () {
20
+ auto end = chrono::high_resolution_clock::now ();
21
+ auto duration = chrono::duration_cast<chrono::milliseconds>(end - begin).count ();
22
+ cerr << duration << " ms elapsed [" << label << " ]" << endl;
23
+ }
24
+ };
15
25
namespace MIT {
16
26
namespace fft {
17
27
#if FFT
@@ -349,7 +359,11 @@ vector<num> eval(const poly &a, const vector<num> &x) {
349
359
per (i, 1 , n) up[i] = up[2 * i] * up[2 * i + 1 ];
350
360
vector<poly> down (2 * n);
351
361
down[1 ] = a % up[1 ];
352
- rep (i, 2 , 2 * n) down[i] = down[i / 2 ] % up[i];
362
+ {
363
+ rep (i, 2 , 2 * n) {
364
+ down[i] = down[i / 2 ] % up[i];
365
+ }
366
+ }
353
367
vector<num> y (n);
354
368
rep (i, 0 , n) y[i] = down[i + n][0 ];
355
369
return y;
@@ -505,7 +519,16 @@ poly &operator-=(poly &a, const poly &b) {
505
519
rep (i, 0 , sz (b)) a[i] = a[i] - b[i];
506
520
return a;
507
521
}
508
- poly &operator *=(poly &a, const poly &b) { return a = conv (a, b); }
522
+
523
+ poly &operator *=(poly &a, const poly &b) {
524
+ if (sz (a) + sz (b) < 100 ){
525
+ poly res (sz (a) + sz (b) - 1 );
526
+ rep (i,0 ,sz (a)) rep (j,0 ,sz (b))
527
+ res[i + j] = (res[i + j] + a[i] * b[j]);
528
+ return (a = res);
529
+ }
530
+ return a = conv (a, b);
531
+ }
509
532
poly operator *(poly a, const num b) {
510
533
poly c = a;
511
534
trav (i, c) i = i * b;
@@ -518,17 +541,6 @@ poly operator*(poly a, const num b) {
518
541
}
519
542
OP (*, *=) OP(+, +=) OP(-, -=);
520
543
poly modK (poly a, int k) { return {a.begin (), a.begin () + min (k, sz (a))}; }
521
- // poly inverse(poly A) {
522
- // poly B = poly({num(1) / A[0]});
523
- // while (sz(B) < sz(A)){
524
- // poly C = B*modK(A, 2*sz(B));
525
- // C = poly(C.begin()+sz(B), C.end());
526
- // C = modK(B*C, sz(B));
527
- // C.insert(C.begin(), sz(B), 0);
528
- // B -= C;
529
- // }
530
- // return modK(B, sz(A));
531
- // }
532
544
poly inverse (poly A) {
533
545
poly B = poly ({num (1 ) / A[0 ]});
534
546
while (sz (B) < sz (A))
@@ -603,9 +615,10 @@ vector<num> eval(const poly &a, const vector<num> &x) {
603
615
rep (i, 0 , n) up[i + n] = poly ({num (0 ) - x[i], 1 });
604
616
for (int i = n - 1 ; i > 0 ; i--)
605
617
up[i] = up[2 * i] * up[2 * i + 1 ];
606
- vector<poly> down (2 * n);
618
+ vector<poly> down (2 * n, poly ( 1 , 0 ) );
607
619
down[1 ] = a % up[1 ];
608
- rep (i, 2 , 2 * n) down[i] = down[i / 2 ] % up[i];
620
+ rep (i, 2 , 2 * n)
621
+ down[i] = down[i / 2 ] % up[i];
609
622
vector<num> y (n);
610
623
rep (i, 0 , n) y[i] = down[i + n][0 ];
611
624
return y;
@@ -624,16 +637,6 @@ poly interp(vector<num> x, vector<num> y) {
624
637
}
625
638
626
639
} // namespace mine
627
- struct timeit {
628
- decltype (chrono::high_resolution_clock::now()) begin;
629
- const string label;
630
- timeit (string label = " ???" ) : label(label) { begin = chrono::high_resolution_clock::now (); }
631
- ~timeit () {
632
- auto end = chrono::high_resolution_clock::now ();
633
- auto duration = chrono::duration_cast<chrono::milliseconds>(end - begin).count ();
634
- cerr << duration << " ms elapsed [" << label << " ]" << endl;
635
- }
636
- };
637
640
pair<mine::poly, MIT::poly> genVec (int sz) {
638
641
mine::poly a;
639
642
MIT::poly am;
@@ -671,7 +674,8 @@ template <class A, class B> void fail(A mine, B mit) {
671
674
cout << endl;
672
675
673
676
}
674
- const int NUMITERS=100 ;
677
+
678
+ const int NUMITERS=10 ;
675
679
template <class A , class B > void testBinary (string name, A f1, B f2, int mxSz = 5 ) {
676
680
for (int it = 0 ; it < NUMITERS; it++) {
677
681
auto a = genVec ((rand () % mxSz) + 1 );
@@ -760,6 +764,7 @@ template <class A, class B> void testPow(string name, A f1, B f2, int mxSz = 5,
760
764
}
761
765
template <class A , class B > void testEval (string name, A f1, B f2, int mxSz = 5 ) {
762
766
for (int it = 0 ; it < NUMITERS; it++) {
767
+ break ;
763
768
auto a = genVec ((rand () % mxSz) + 1 );
764
769
auto b = genVec ((rand () % mxSz)+1 );
765
770
auto res = f1 (a.first , b.first );
@@ -816,7 +821,7 @@ template <class A, class B> void testInterp(string name, A f1, B f2, int mxSz =
816
821
signed main () {
817
822
ios::sync_with_stdio (0 );
818
823
cin.tie (0 );
819
- int SZ = 10000 ;
824
+ int SZ = 100000 ;
820
825
testBinary (" sub" , mine::operator -, MIT::operator -, SZ);
821
826
testBinary (" add" , mine::operator +, MIT::operator +, SZ);
822
827
testBinary (" div" , mine::operator /, MIT::operator /, SZ);
@@ -826,7 +831,7 @@ signed main() {
826
831
testUnary (" integral" , mine::integr, MIT::integ, SZ);
827
832
testUnary (" log" , mine::log, MIT::log, SZ);
828
833
testUnary (" exp" , mine::exp, MIT::exp, SZ);
829
- SZ = 1000 ;
834
+ SZ = 10000 ;
830
835
testPow (" pow" , mine::pow, MIT::pow, SZ, 5 );
831
836
testEval (" eval" , mine::eval, MIT::eval, SZ);
832
837
testInterp (" interp" , mine::interp, MIT::interp, SZ);
0 commit comments