Advertisement
Guest User

Untitled

a guest
Jan 28th, 2020
96
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.71 KB | None | 0 0
  1.  
  2. #include <iostream>
  3. #include <vector>
  4. #include <set>
  5. #include <algorithm>
  6. #include <ctime>
  7. #include <cmath>
  8. #include <map>
  9. #include <assert.h>
  10. #include <fstream>
  11. #include <cstdlib>
  12. #include <random>
  13. #include <iomanip>
  14.  
  15. using namespace std;
  16.  
  17. #define sqr(a) ((a)*(a))
  18. #define all(a) (a).begin(), (a).end()
  19.  
  20. const long long MOD = (long long) 1e9 + 7;
  21. const long long MAX_N = (long long) 100;
  22.  
  23. long long binPow(long long a, long long b) {
  24. if (b == 0)
  25. return 1;
  26.  
  27. long long ans = binPow(a, b / 2);
  28. ans = ans * ans % MOD;
  29.  
  30. if (b % 2)
  31. ans = ans * a % MOD;
  32.  
  33. return ans;
  34. }
  35.  
  36. // make it understandable one day...
  37. namespace fft {
  38.  
  39. typedef double dbl;
  40.  
  41. struct num {
  42. dbl x, y;
  43. num() { x = y = 0; }
  44. num(dbl x_, dbl y_) : x(x_), y(y_) {}
  45. };
  46.  
  47. inline num operator+(num a, num b) { return num(a.x + b.x, a.y + b.y); }
  48. inline num operator-(num a, num b) { return num(a.x - b.x, a.y - b.y); }
  49. inline num operator*(num a, num b) { return num(a.x * b.x - a.y * b.y, a.x * b.y + a.y * b.x); }
  50. inline num conj(num a) { return num(a.x, -a.y); }
  51.  
  52. int base = 1;
  53. vector<num> roots = {{0, 0}, {1, 0}};
  54. vector<int> rev = {0, 1};
  55.  
  56. const dbl PI = static_cast<dbl>(acosl(-1.0));
  57.  
  58. void ensure_base(int nbase) {
  59. if (nbase <= base) {
  60. return;
  61. }
  62. rev.resize(1 << nbase);
  63. for (int i = 0; i < (1 << nbase); i++) {
  64. rev[i] = (rev[i >> 1] >> 1) + ((i & 1) << (nbase - 1));
  65. }
  66. roots.resize(1 << nbase);
  67. while (base < nbase) {
  68. dbl angle = 2 * PI / (1 << (base + 1));
  69. // num z(cos(angle), sin(angle));
  70. for (int i = 1 << (base - 1); i < (1 << base); i++) {
  71. roots[i << 1] = roots[i];
  72. // roots[(i << 1) + 1] = roots[i] * z;
  73. dbl angle_i = angle * (2 * i + 1 - (1 << base));
  74. roots[(i << 1) + 1] = num(cos(angle_i), sin(angle_i));
  75. }
  76. base++;
  77. }
  78. }
  79.  
  80. void fft(vector<num>& a, int n = -1) {
  81. if (n == -1) {
  82. n = (int) a.size();
  83. }
  84. assert((n & (n - 1)) == 0);
  85. int zeros = __builtin_ctz(n);
  86. ensure_base(zeros);
  87. int shift = base - zeros;
  88. for (int i = 0; i < n; i++) {
  89. if (i < (rev[i] >> shift)) {
  90. swap(a[i], a[rev[i] >> shift]);
  91. }
  92. }
  93. for (int k = 1; k < n; k <<= 1) {
  94. for (int i = 0; i < n; i += 2 * k) {
  95. for (int j = 0; j < k; j++) {
  96. num z = a[i + j + k] * roots[j + k];
  97. a[i + j + k] = a[i + j] - z;
  98. a[i + j] = a[i + j] + z;
  99. }
  100. }
  101. }
  102. }
  103.  
  104. vector<num> fa, fb;
  105.  
  106. vector<int64_t> square(const vector<int>& a) {
  107. if (a.empty()) {
  108. return {};
  109. }
  110. int need = (int) a.size() + (int) a.size() - 1;
  111. int nbase = 1;
  112. while ((1 << nbase) < need) nbase++;
  113. ensure_base(nbase);
  114. int sz = 1 << nbase;
  115. if ((sz >> 1) > (int) fa.size()) {
  116. fa.resize(sz >> 1);
  117. }
  118. for (int i = 0; i < (sz >> 1); i++) {
  119. int x = (2 * i < (int) a.size() ? a[2 * i] : 0);
  120. int y = (2 * i + 1 < (int) a.size() ? a[2 * i + 1] : 0);
  121. fa[i] = num(x, y);
  122. }
  123. fft(fa, sz >> 1);
  124. num r(1.0 / (sz >> 1), 0.0);
  125. for (int i = 0; i <= (sz >> 2); i++) {
  126. int j = ((sz >> 1) - i) & ((sz >> 1) - 1);
  127. num fe = (fa[i] + conj(fa[j])) * num(0.5, 0);
  128. num fo = (fa[i] - conj(fa[j])) * num(0, -0.5);
  129. num aux = fe * fe + fo * fo * roots[(sz >> 1) + i] * roots[(sz >> 1) + i];
  130. num tmp = fe * fo;
  131. fa[i] = r * (conj(aux) + num(0, 2) * conj(tmp));
  132. fa[j] = r * (aux + num(0, 2) * tmp);
  133. }
  134. fft(fa, sz >> 1);
  135. vector<int64_t> res(need);
  136. for (int i = 0; i < need; i++) {
  137. res[i] = llround(i % 2 == 0 ? fa[i >> 1].x : fa[i >> 1].y);
  138. }
  139. return res;
  140. }
  141.  
  142. vector<int64_t> multiply(const vector<int>& a, const vector<int>& b) {
  143. if (a.empty() || b.empty()) {
  144. return {};
  145. }
  146. if (a == b) {
  147. return square(a);
  148. }
  149. int need = (int) a.size() + (int) b.size() - 1;
  150. int nbase = 1;
  151. while ((1 << nbase) < need) nbase++;
  152. ensure_base(nbase);
  153. int sz = 1 << nbase;
  154. if (sz > (int) fa.size()) {
  155. fa.resize(sz);
  156. }
  157. for (int i = 0; i < sz; i++) {
  158. int x = (i < (int) a.size() ? a[i] : 0);
  159. int y = (i < (int) b.size() ? b[i] : 0);
  160. fa[i] = num(x, y);
  161. }
  162. fft(fa, sz);
  163. num r(0, -0.25 / (sz >> 1));
  164. for (int i = 0; i <= (sz >> 1); i++) {
  165. int j = (sz - i) & (sz - 1);
  166. num z = (fa[j] * fa[j] - conj(fa[i] * fa[i])) * r;
  167. fa[j] = (fa[i] * fa[i] - conj(fa[j] * fa[j])) * r;
  168. fa[i] = z;
  169. }
  170. for (int i = 0; i < (sz >> 1); i++) {
  171. num A0 = (fa[i] + fa[i + (sz >> 1)]) * num(0.5, 0);
  172. num A1 = (fa[i] - fa[i + (sz >> 1)]) * num(0.5, 0) * roots[(sz >> 1) + i];
  173. fa[i] = A0 + A1 * num(0, 1);
  174. }
  175. fft(fa, sz >> 1);
  176. vector<int64_t> res(need);
  177. for (int i = 0; i < need; i++) {
  178. res[i] = llround(i % 2 == 0 ? fa[i >> 1].x : fa[i >> 1].y);
  179. }
  180. return res;
  181. }
  182. }
  183.  
  184. int eval(char c) {
  185. if (c == '?') {
  186. return 0;
  187. }
  188. if (c == 'o') {
  189. return 1;
  190. }
  191. if (c == 'k') {
  192. return -1;
  193. }
  194. throw;
  195. }
  196.  
  197. const int maxn = 1e6;
  198. #define ll long long
  199.  
  200. ll dp[maxn];
  201. int val[maxn];
  202. int cnto[maxn], cntk[maxn];
  203.  
  204. void upmax(ll& x, ll y) {
  205. x = max(x, y);
  206. }
  207.  
  208. int main() {
  209. // freopen("input.txt", "r", stdin);
  210. ios_base::sync_with_stdio(0);
  211. cin.tie(0);
  212. // srand(time(0));
  213.  
  214. int o, k;
  215. cin >> o >> k;
  216.  
  217. string s, p;
  218. cin >> s >> p;
  219.  
  220. int n = s.size(), m = p.size();
  221. vector<int> a, b;
  222. a.resize(n);
  223. b.resize(m);
  224.  
  225. for (int i = 0; i < n; i++) {
  226. a[n - i - 1] = eval(s[i]);
  227. cnto[i + 1] = cnto[i] + (s[i] == 'o');
  228. cntk[i + 1] = cntk[i] + (s[i] == 'k');
  229. }
  230.  
  231. int cnt0 = 0;
  232. for (int i = 0; i < m; i++) {
  233. b[i] = eval(p[i]);
  234. cnt0 += b[i] == 0;
  235. }
  236.  
  237. // for (int i = 0; i < n; i++) {
  238. // cout << a[i] << ' ';
  239. // }
  240. // cout << endl;
  241.  
  242. // for (int i = 0; i < m; i++) {
  243. // cout << b[i] << ' ';
  244. // }
  245. auto c = fft::multiply(a, b);
  246. // cout << c[7];
  247. // return 0;
  248.  
  249. for (int i = 0; i + m <= n; i++) {
  250. if (n - i - 1 >= c.size()) {
  251. throw;
  252. }
  253. // cout << i + n - 1 << ' ' << c[n - i - 1] << endl;
  254. int x = c[n - i - 1];
  255. int q = cnt0;
  256. val[i] = m - cnt0 - (x + m + cnt0) / 2;
  257. // cout << x << ' ' << q << ' ' << m << endl;
  258. // int y = x - m + q;
  259.  
  260. // assert(y % 2 == 0);
  261. // val[i] = m - q - y / 2;
  262. // cout << val[i] << endl;
  263. }
  264.  
  265. for (int i = 0; i < n; i++) {
  266. if (i + m <= n) {
  267. long long kek = 1ll * o * (cnto[i + m] - cnto[i]) + 1ll * k * (cntk[i + m] - cntk[i]);
  268. for (int j = 0; j < val[i] && kek > 0; j++) {
  269. kek /= 2;
  270. }
  271. upmax(dp[i + m], dp[i] + kek);
  272. }
  273. upmax(dp[i + 1], dp[i]);
  274. }
  275.  
  276. cout << dp[n];
  277. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement