@@ -11,6 +11,7 @@ using namespace cp_algo::math;
1111
1212using fft::ftype;
1313using fft::point;
14+ using fft::vftype;
1415using fft::cvector;
1516
1617void semicorr (auto &a, auto &b) {
@@ -20,11 +21,28 @@ void semicorr(auto &a, auto &b) {
2021 a.ifft ();
2122}
2223
23- auto is_integer = [](point a) {
24+ vftype abs (vftype a) {
25+ return a < 0 ? -a : a;
26+ }
27+
28+ using v4di [[gnu::vector_size(32 )]] = long ;
29+
30+ auto round (vftype a) {
31+ return __builtin_convertvector (__builtin_convertvector (a < 0 ? a - 0.5 : a + 0.5 , v4di), vftype);
32+ }
33+
34+ void print (auto r) {
35+ for (int z = 0 ; z < 4 ; z++) {
36+ cout << r[z] << ' ' ;
37+ }
38+ cout << endl;
39+ }
40+
41+ auto is_integer (auto a) {
2442 static const double eps = 1e-8 ;
2543 return abs (imag (a)) < eps
2644 && abs (real (a) - round (real (a))) < eps;
27- };
45+ }
2846
2947string matches (string const & A, string const & B, char wild = ' *' ) {
3048 static const int sigma = 26 ;
@@ -48,12 +66,17 @@ string matches(string const& A, string const& B, char wild = '*') {
4866 }
4967 cp_algo::checkpoint (" cvector fill" );
5068 semicorr (P[0 ], P[1 ]);
51- string ans (size (A) - size (B) + 1 , ' 0' );
52- for (size_t j = 0 ; j < size (ans); j++) {
53- ans[j] = ' 0' + is_integer (P[0 ].get (size (B) - 1 + j));
69+ string ans (size (P[0 ]), ' 0' );
70+ auto start = (size (B) - 1 ) / fft::flen * fft::flen;
71+ for (size_t j = start; j < size (ans); j += fft::flen) {
72+ auto r = P[0 ].at (j);
73+ auto check = is_integer (r);
74+ for (int z = 0 ; z < 4 ; z++) {
75+ ans[j + z] ^= (bool )check[z];
76+ }
5477 }
5578 cp_algo::checkpoint (" fill answer" );
56- return ans;
79+ return ans. substr ( size (B) - 1 , size (A) - size (B) + 1 ) ;
5780}
5881
5982void solve () {
0 commit comments