@@ -11,6 +11,7 @@ using namespace cp_algo::math;
11
11
12
12
using fft::ftype;
13
13
using fft::point;
14
+ using fft::vftype;
14
15
using fft::cvector;
15
16
16
17
void semicorr (auto &a, auto &b) {
@@ -20,11 +21,28 @@ void semicorr(auto &a, auto &b) {
20
21
a.ifft ();
21
22
}
22
23
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) {
24
42
static const double eps = 1e-8 ;
25
43
return abs (imag (a)) < eps
26
44
&& abs (real (a) - round (real (a))) < eps;
27
- };
45
+ }
28
46
29
47
string matches (string const & A, string const & B, char wild = ' *' ) {
30
48
static const int sigma = 26 ;
@@ -48,12 +66,17 @@ string matches(string const& A, string const& B, char wild = '*') {
48
66
}
49
67
cp_algo::checkpoint (" cvector fill" );
50
68
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
+ }
54
77
}
55
78
cp_algo::checkpoint (" fill answer" );
56
- return ans;
79
+ return ans. substr ( size (B) - 1 , size (A) - size (B) + 1 ) ;
57
80
}
58
81
59
82
void solve () {
0 commit comments