@@ -385,7 +385,7 @@ struct Mod {
385
385
Mod r = *this ^ (e / 2 ); r = r * r;
386
386
return e&1 ? *this * r : r;
387
387
}
388
- operator ll () { return x; }
388
+ explicit operator ll () { return x; }
389
389
};
390
390
391
391
typedef Mod num;
@@ -583,9 +583,10 @@ poly exp(poly a) {
583
583
return modK (b, sz (a));
584
584
}
585
585
poly pow (poly a, ll m) {
586
- int p = 0 ; int n = sz (a);
586
+ int p = 0 , n = sz (a);
587
587
while (p < sz (a) && a[p].x == 0 )
588
588
++p;
589
+ if (ll (m)*p >= sz (a)) return poly (sz (a));
589
590
num j = a[p];
590
591
a = {a.begin () + p, a.end ()};
591
592
a = a * (num (1 ) / j);
@@ -612,14 +613,13 @@ vector<num> eval(const poly &a, const vector<num> &x) {
612
613
613
614
poly interp (vector<num> x, vector<num> y) {
614
615
int n=sz (x);
615
- assert (n);
616
616
vector<poly> up (n*2 );
617
617
rep (i,0 ,n) up[i+n] = poly ({num (0 )-x[i], num (1 )});
618
- per (i, 1 ,n ) up[i] = up[2 *i]*up[2 *i+1 ];
618
+ for ( int i=n- 1 ; i> 0 ;i-- ) up[i] = up[2 *i]*up[2 *i+1 ];
619
619
vector<num> a = eval (deriv (up[1 ]), x);
620
620
vector<poly> down (2 *n);
621
621
rep (i,0 ,n) down[i+n] = poly ({y[i]*(num (1 )/a[i])});
622
- per (i, 1 ,n ) down[i] = down[i*2 ] * up[i*2 +1 ] + down[i*2 +1 ] * up[i*2 ];
622
+ for ( int i=n- 1 ;i> 0 ;i-- ) down[i] = down[i*2 ] * up[i*2 +1 ] + down[i*2 +1 ] * up[i*2 ];
623
623
return down[1 ];
624
624
}
625
625
@@ -729,10 +729,10 @@ template <class A, class B> void testUnary(string name, A f1, B f2, int mxSz = 5
729
729
}
730
730
cout<<endl;
731
731
}
732
- template <class A , class B > void testPow (string name, A f1, B f2, int mxSz = 5 ) {
732
+ template <class A , class B > void testPow (string name, A f1, B f2, int mxSz = 5 , int mxPref= 5 ) {
733
733
for (int it = 0 ; it < NUMITERS; it++) {
734
734
auto a = genVec ((rand () % mxSz) + 1 );
735
- int pref = rand ()%5 ;
735
+ int pref = rand ()%mxSz ;
736
736
for (int j=0 ; j<pref; j++) {
737
737
a.first .insert (a.first .begin (), mine::num (0 ));
738
738
a.second .insert (a.second .begin (), MIT::num (0 ));
@@ -745,6 +745,29 @@ template <class A, class B> void testPow(string name, A f1, B f2, int mxSz = 5)
745
745
assert (checkEqual (res, t));
746
746
}
747
747
cout << name + " tests passed!" << endl;
748
+ {
749
+ timeit x (" mine" );
750
+ for (int it = 0 ; it < NUMITERS; it++) {
751
+ auto a = genVec ((rand () % mxSz) + 1 );
752
+ int pref = rand ()%mxPref;
753
+ for (int j=0 ; j<pref; j++)
754
+ a.first .insert (a.first .begin (), mine::num (0 ));
755
+ int p = rand () % mxSz;
756
+ f1 (a.first , p);
757
+ }
758
+ }
759
+ {
760
+ timeit x (" mit" );
761
+ for (int it = 0 ; it < NUMITERS; it++) {
762
+ auto a = genVec ((rand () % mxSz) + 1 );
763
+ int pref = rand ()%mxPref;
764
+ for (int j=0 ; j<pref; j++)
765
+ a.second .insert (a.second .begin (), MIT::num (0 ));
766
+ int p = rand () % mxSz;
767
+ f2 (a.second , p);
768
+ }
769
+ }
770
+ cout<<endl;
748
771
}
749
772
template <class A , class B > void testEval (string name, A f1, B f2, int mxSz = 5 ) {
750
773
for (int it = 0 ; it < NUMITERS; it++) {
@@ -757,6 +780,23 @@ template <class A, class B> void testEval(string name, A f1, B f2, int mxSz = 5)
757
780
assert (checkEqual (res, t));
758
781
}
759
782
cout << name + " tests passed!" << endl;
783
+ {
784
+ timeit x (" mine" );
785
+ for (int it = 0 ; it < NUMITERS; it++) {
786
+ auto a = genVec ((rand () % mxSz) + 1 );
787
+ auto b = genVec ((rand () % mxSz)+1 );
788
+ f1 (a.first , b.first );
789
+ }
790
+ }
791
+ {
792
+ timeit x (" MIT" );
793
+ for (int it = 0 ; it < NUMITERS; it++) {
794
+ auto a = genVec ((rand () % mxSz) + 1 );
795
+ auto b = genVec ((rand () % mxSz)+1 );
796
+ f2 (a.second , b.second );
797
+ }
798
+ }
799
+ cout<<endl;
760
800
}
761
801
template <class A , class B > void testInterp (string name, A f1, B f2, int mxSz = 5 ) {
762
802
for (int it = 0 ; it < NUMITERS; it++) {
@@ -770,6 +810,23 @@ template <class A, class B> void testInterp(string name, A f1, B f2, int mxSz =
770
810
assert (checkEqual (res, t));
771
811
}
772
812
cout << name + " tests passed!" << endl;
813
+ {
814
+ timeit x (" mine" );
815
+ for (int it = 0 ; it < NUMITERS; it++) {
816
+ auto a = genVec ((rand () % mxSz) + 1 );
817
+ auto b = genVec ((rand () % mxSz)+1 );
818
+ f1 (a.first , b.first );
819
+ }
820
+ }
821
+ {
822
+ timeit x (" MIT" );
823
+ for (int it = 0 ; it < NUMITERS; it++) {
824
+ auto a = genVec ((rand () % mxSz) + 1 );
825
+ auto b = genVec ((rand () % mxSz)+1 );
826
+ f2 (a.second , b.second );
827
+ }
828
+ }
829
+ cout<<endl;
773
830
}
774
831
signed main () {
775
832
ios::sync_with_stdio (0 );
@@ -785,7 +842,7 @@ signed main() {
785
842
testUnary (" log" , mine::log, MIT::log, SZ);
786
843
testUnary (" exp" , mine::exp, MIT::exp, SZ);
787
844
SZ = 1000 ;
788
- testPow (" pow" , mine::pow, MIT::pow, SZ);
845
+ testPow (" pow" , mine::pow, MIT::pow, SZ, 5 );
789
846
testEval (" eval" , mine::eval, MIT::eval, SZ);
790
847
testInterp (" interp" , mine::interp, MIT::interp, SZ);
791
848
return 0 ;
0 commit comments