Advertisement
GerONSo

J open nlogn персДО + копель

Jan 9th, 2019
105
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.71 KB | None | 0 0
  1. /*
  2. ┓┏┓┏┓┃
  3. ┛┗┛┗┛┃
  4. ┓┏┓┏┓┃
  5. ┛┗┛┗┛┃
  6. ┓┏┓┏┓┃\○/
  7. ┛┗┛┗┛┃ / /
  8. ┓┏┓┏┓┃ノ
  9. ┛┗┛┗┛┃
  10. ┓┏┓┏┓┃
  11. ┛┗┛┗┛┃
  12. ┓┏┓┏┓┃
  13. ┛┗┛┗┛┃
  14. ┓┏┓┏┓┃
  15. ┛┗┛┗┛┃
  16. ┓┏┓┏┓┃┓
  17. ┛┗┛┗┛┃┃
  18. MIPTCLASSICMIPTCLASSICMIPTCLASSICMIPTCLASSICMIPTCLASSICMIPTCLASSIC
  19. */
  20.  
  21. #define pragma
  22.  
  23. #ifdef pragma
  24. #pragma GCC optimize("Ofast")
  25. #pragma GCC optimize("no-stack-protector")
  26. #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
  27. #pragma GCC optimize("unroll-loops")
  28. #pragma GCC diagnostic ignored "-Wunused-result"
  29. #endif // pragma
  30.  
  31. #include<bits/stdc++.h>
  32. #include <ext/pb_ds/assoc_container.hpp>
  33. #include <ext/pb_ds/tree_policy.hpp>
  34.  
  35. #define ll long long
  36. #define all(x) begin(x), end(x)
  37. #define pb push_back
  38. #define x first
  39. #define y second
  40. #define int long long
  41. #define zero(two) memset(two, 0, sizeof(two))
  42.  
  43. using namespace std;
  44. using namespace __gnu_pbds;
  45.  
  46.  
  47. typedef vector<int> vi;
  48. typedef vector<bool> vb;
  49. typedef pair<int, int> pii;
  50. typedef long double ld;
  51. typedef vector<vi> matrix;
  52. template<typename T>
  53. using kawaii_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
  54.  
  55. const ld PI = atan2(0, -1);
  56.  
  57. void seriy() {
  58. ios::sync_with_stdio(0);
  59. cin.tie(0);
  60. cout.tie(0);
  61. cout << fixed << setprecision(10);
  62. #if 1
  63. freopen("input", "r", stdin);
  64. freopen("output", "w", stdout);
  65. #endif
  66. }
  67.  
  68. template <class T = int> inline T readInt();
  69. inline double readDouble();
  70. inline int readUInt();
  71. inline int readChar(); // first non-blank character
  72. inline void readWord( char *s );
  73. inline bool readLine( char *s ); // do not save '\n'
  74. inline bool isEof();
  75. inline int getChar();
  76. inline int peekChar();
  77. inline bool seekEof();
  78. inline void skipBlanks();
  79.  
  80. template <class T> inline void writeInt( T x, char end = 0, int len = -1 );
  81. inline void writeChar( int x );
  82. inline void writeWord( const char *s );
  83. inline void writeDouble( double x, int len = 0 );
  84. inline void flush();
  85.  
  86. static struct buffer_flusher_t {
  87. ~buffer_flusher_t() {
  88. flush();
  89. }
  90. } buffer_flusher;
  91.  
  92. /** Read */
  93.  
  94. static const int buf_size = 4096;
  95.  
  96. static unsigned char buf[buf_size];
  97. static int buf_len = 0, buf_pos = 0;
  98.  
  99. inline bool isEof() {
  100. if (buf_pos == buf_len) {
  101. buf_pos = 0, buf_len = fread(buf, 1, buf_size, stdin);
  102. if (buf_pos == buf_len)
  103. return 1;
  104. }
  105. return 0;
  106. }
  107.  
  108.  
  109. inline int getChar() {
  110. return isEof() ? -1 : buf[buf_pos++];
  111. }
  112.  
  113. inline int peekChar() {
  114. return isEof() ? -1 : buf[buf_pos];
  115. }
  116.  
  117. inline bool seekEof() {
  118. int c;
  119. while ((c = peekChar()) != -1 && c <= 32)
  120. buf_pos++;
  121. return c == -1;
  122. }
  123.  
  124. inline void skipBlanks() {
  125. while (!isEof() && buf[buf_pos] <= 32U)
  126. buf_pos++;
  127. }
  128.  
  129. inline int readChar() {
  130. int c = getChar();
  131. while (c != -1 && c <= 32)
  132. c = getChar();
  133. return c;
  134. }
  135.  
  136. inline int readUInt() {
  137. int c = readChar(), x = 0;
  138. while ('0' <= c && c <= '9')
  139. x = x * 10 + c - '0', c = getChar();
  140. return x;
  141. }
  142.  
  143. template <class T>
  144. inline T readInt() {
  145. int s = 1, c = readChar();
  146. T x = 0;
  147. if (c == '-')
  148. s = -1, c = getChar();
  149. else if (c == '+')
  150. c = getChar();
  151. while ('0' <= c && c <= '9')
  152. x = x * 10 + c - '0', c = getChar();
  153. return s == 1 ? x : -x;
  154. }
  155.  
  156. inline double readDouble() {
  157. int s = 1, c = readChar();
  158. double x = 0;
  159. if (c == '-')
  160. s = -1, c = getChar();
  161. while ('0' <= c && c <= '9')
  162. x = x * 10 + c - '0', c = getChar();
  163. if (c == '.') {
  164. c = getChar();
  165. double coef = 1;
  166. while ('0' <= c && c <= '9')
  167. x += (c - '0') * (coef *= 1e-1), c = getChar();
  168. }
  169. return s == 1 ? x : -x;
  170. }
  171.  
  172. inline void readWord( char *s ) {
  173. int c = readChar();
  174. while (c > 32)
  175. *s++ = c, c = getChar();
  176. *s = 0;
  177. }
  178.  
  179. inline bool readLine( char *s ) {
  180. int c = getChar();
  181. while (c != '\n' && c != -1)
  182. *s++ = c, c = getChar();
  183. *s = 0;
  184. return c != -1;
  185. }
  186.  
  187. /** Write */
  188.  
  189. static int write_buf_pos = 0;
  190. static char write_buf[buf_size];
  191.  
  192. inline void writeChar( int x ) {
  193. if (write_buf_pos == buf_size)
  194. fwrite(write_buf, 1, buf_size, stdout), write_buf_pos = 0;
  195. write_buf[write_buf_pos++] = x;
  196. }
  197.  
  198. inline void flush() {
  199. if (write_buf_pos)
  200. fwrite(write_buf, 1, write_buf_pos, stdout), write_buf_pos = 0;
  201. }
  202.  
  203. template <class T>
  204. inline void writeInt( T x, char end, int output_len ) {
  205. if (x < 0)
  206. writeChar('-'), x = -x;
  207.  
  208. char s[24];
  209. int n = 0;
  210. while (x || !n)
  211. s[n++] = '0' + x % 10, x /= 10;
  212. while (n < output_len)
  213. s[n++] = '0';
  214. while (n--)
  215. writeChar(s[n]);
  216. if (end)
  217. writeChar(end);
  218. }
  219.  
  220. inline void writeWord( const char *s ) {
  221. while (*s)
  222. writeChar(*s++);
  223. }
  224.  
  225. inline void writeDouble( double x, int output_len ) {
  226. if (x < 0)
  227. writeChar('-'), x = -x;
  228. int t = (int)x;
  229. writeInt(t), x -= t;
  230. writeChar('.');
  231. for (int i = output_len - 1; i > 0; i--) {
  232. x *= 10;
  233. t = std::min(9ll, (int)x);
  234. writeChar('0' + t), x -= t;
  235. }
  236. x *= 10;
  237. t = std::min(9ll, (int)(x + 0.5));
  238. writeChar('0' + t);
  239. }
  240.  
  241. struct node {
  242. int sum;
  243. node *left;
  244. node *right;
  245. };
  246.  
  247. const int INF = 1e9 + 7;
  248. const int MAXN = 1e6 + 10;
  249. const int BASE = 47;
  250. const int MOD = 1e9 + 7;
  251. const int BASE2 = 43;
  252. const int MOD2 = 998244353ll;
  253.  
  254. vi p(MAXN), cnt(MAXN), c(MAXN);
  255. vi pn(MAXN), cn(MAXN);
  256. vi h, ht, h2, ht2;
  257. vi pows, pows2;
  258. int n;
  259. string t, s;
  260.  
  261. void build(node *&v, int tl, int tr, int pos) {
  262. if(tl == tr) {
  263. if(tl == pos) v -> sum = 1;
  264. return;
  265. }
  266. int tm = (tl + tr) >> 1;
  267. v -> left = new node();
  268. v -> right = new node();
  269. build(v -> left, tl, tm, pos);
  270. build(v -> right, tm + 1, tr, pos);
  271. v -> sum = v -> left -> sum + v -> right -> sum;
  272. }
  273.  
  274. int get(node *&v, int tl, int tr, int l, int r) {
  275. if(tl > r || tr < l) {
  276. return 0;
  277. }
  278. if(tl >= l && tr <= r) {
  279. return v -> sum;
  280. }
  281. int tm = (tl + tr) >> 1;
  282. int left = get(v -> left, tl, tm, l, r);
  283. int right = get(v -> right, tm + 1, tr, l, r);
  284. return left + right;
  285. }
  286.  
  287. void update(node *&v, node *&v2, int tl, int tr, int pos) {
  288. // cerr << tl << " " << tr << '\n';
  289. if(tl > pos || tr < pos) {
  290. return;
  291. }
  292. if(tl == tr) {
  293. (v -> sum)++;
  294. // cerr << tl << " " << tr << " " << v -> sum << '\n';
  295. return;
  296. }
  297. int tm = (tl + tr) >> 1;
  298. if(pos > tm) {
  299. v -> left = v2 -> left;
  300. v -> right = new node();
  301. update(v -> right, v2 -> right, tm + 1, tr, pos);
  302. }
  303. else {
  304. v -> right = v2 -> right;
  305. v -> left = new node();
  306. update(v -> left, v2 -> left, tl, tm, pos);
  307. }
  308. v -> sum = v -> left -> sum + v -> right -> sum;
  309. // cerr << tl << " " << tr << " " << v -> sum << '\n';
  310. }
  311.  
  312. vi get_hash(string s) {
  313. int n = s.size();
  314. vi ans(n + 1);
  315. for(int i = 1; i <= n; i++) {
  316. ans[i] = (ans[i - 1] + s[i - 1] * pows[i - 1]) % MOD;
  317. }
  318. return ans;
  319. }
  320.  
  321. vi get_hash2(string s) {
  322. int n = s.size();
  323. vi ans(n + 1);
  324. for(int i = 1; i <= n; i++) {
  325. ans[i] = (ans[i - 1] + s[i - 1] * pows2[i - 1]) % MOD2;
  326. }
  327. return ans;
  328. }
  329.  
  330. int subhash(int l, int r, vi &h) {
  331. return (((h[r + 1] - h[l] + MOD) % MOD) * pows[n - l - 1]) % MOD;
  332. }
  333.  
  334. int subhash2(int l, int r, vi &h) {
  335. return (((h[r + 1] - h[l] + MOD2) % MOD2) * pows2[n - l - 1]) % MOD2;
  336. }
  337.  
  338. bool compare2(int l1, int r1, int l2, int r2) {
  339. return subhash2(l1, r1, ht2) == subhash2(l2, r2, h2);
  340. }
  341.  
  342. bool compare(int l1, int r1, int l2, int r2) {
  343. return subhash(l1, r1, ht) == subhash(l2, r2, h) && (subhash(l1, r1, ht) == subhash(l2, r2, h)) == compare2(l1, r1, l2, r2);
  344. }
  345.  
  346. signed main() {
  347. seriy();
  348. cin >> t >> s;
  349. int dn = s.size();
  350. s += t;
  351. s += '$';
  352. n = s.size();
  353.  
  354. int m = t.size();
  355. int mx = max(n, m);
  356. pows.resize(mx);
  357. pows[0] = 1;
  358. pows2.resize(mx);
  359. pows2[0] = 1;
  360. for(int i = 1; i < mx; i++) {
  361. pows[i] = pows[i - 1] * BASE;
  362. pows[i] %= MOD;
  363. pows2[i] = pows2[i - 1] * BASE2;
  364. pows2[i] %= MOD2;
  365. }
  366. h = get_hash(s);
  367. ht = get_hash(t);
  368. h2 = get_hash2(s);
  369. ht2 = get_hash2(t);
  370. for(int i = 0; i < n; i++) {
  371. cnt[s[i]]++;
  372. }
  373. for(int i = 1; i < MAXN; i++) {
  374. cnt[i] += cnt[i - 1];
  375. }
  376. for(int i = 0; i < n; i++) {
  377. p[--cnt[s[i]]] = i;
  378. }
  379. c[p[0]] = 0;
  380. int cur = 1;
  381. for(int i = 1; i < n; i++) {
  382. if (s[p[i]] != s[p[i - 1]]) {
  383. ++cur;
  384. }
  385. c[p[i]] = cur - 1;
  386. }
  387.  
  388. for(int h = 0; (1 << h) < n; ++h) {
  389. for(int i = 0; i < n; i++) {
  390. pn[i] = (p[i] + n - (1 << h)) % n;
  391. }
  392. cnt.assign(MAXN, 0);
  393. for(int i = 0; i < n; i++) {
  394. cnt[c[pn[i]]]++;
  395. }
  396. for(int i = 1; i < cur; i++) {
  397. cnt[i] += cnt[i - 1];
  398. }
  399. for(int i = n - 1; i >= 0; i--) {
  400. p[--cnt[c[pn[i]]]] = pn[i];
  401. }
  402. cn[p[0]] = 0;
  403. cur = 1;
  404. for(int i = 1; i < n; i++) {
  405. int m1 = (p[i] + (1 << h)) % n, m2 = (p[i - 1] + (1 << h)) % n;
  406. if (c[p[i]] != c[p[i - 1]] || c[m1] != c[m2]) {
  407. cur++;
  408. }
  409. cn[p[i]] = cur - 1;
  410. }
  411. c = cn;
  412. }
  413. n--;
  414. for(int i = 0; i < n; i++) {
  415. p[i] = p[i + 1];
  416. }
  417. vi rp(n);
  418. for(int i = 0; i < n; i++) {
  419. rp[p[i]] = i;
  420. }
  421. vector<node*> roots(n + 1);
  422. roots[0] = new node();
  423. build(roots[0], 0, n, -1);
  424. for(int i = 1; i <= n; i++) {
  425. roots[i] = new node();
  426. update(roots[i], roots[i - 1], 0, n, p[i - 1]);
  427. }
  428. // cerr << compare3(0, 1, p[0], 6);
  429. // cerr << "-------\n";
  430. int q;
  431. cin >> q;
  432. while(q--) {
  433. int l, r, l1, r1;
  434. cin >> l >> r >> l1 >> r1;
  435. l--;
  436. r--;
  437. l1--;
  438. r1--;
  439. if(r - l > r1 - l1) {
  440. writeWord("0\n");
  441. continue;
  442. }
  443. if(n == 1) {
  444. if(r == l) {
  445. if(t[l] == s[l1]) {
  446. writeWord("1\n");
  447. }
  448. else {
  449. writeWord("0\n");
  450. }
  451. }
  452. else {
  453. writeWord("0\n");
  454. }
  455. continue;
  456. }
  457. int resLeft, resRight;
  458. int tl = rp[dn + l], tr = n;
  459. while(tr - tl > 1) {
  460. int mid = (tr + tl) >> 1;
  461. int suf = p[mid];
  462. if(n - suf < r - l + 1) {
  463. tr = mid;
  464. }
  465. else if(compare(l, r, suf, suf + r - l)) {
  466. tl = mid;
  467. }
  468. else {
  469. tr = mid;
  470. }
  471. // cerr << mid << " !" << '\n';
  472. // cerr << mid << " " << compare2(l, r, suf, r1) << '\n';
  473. // cerr << "------\n";
  474. }
  475.  
  476. resRight = tl;
  477. tl = -1, tr = rp[dn + l];
  478. // cerr << compare()
  479. while(tr - tl > 1) {
  480. int mid = (tl + tr) >> 1;
  481. int suf = p[mid];
  482. // cerr << mid << " ";
  483. if(n - suf < r - l + 1) {
  484. // cerr << "l\n";
  485. tl = mid;
  486. }
  487. else if(compare(l, r, suf, suf + r - l)) {
  488. // cerr << "r\n";
  489. tr = mid;
  490. }
  491. else {
  492. // cerr << "l\n";
  493. tl = mid;
  494. }
  495. // cerr << '\n';
  496. // cerr << mid << " !" << '\n';
  497.  
  498. // cerr << mid << " " << compare3(l, r, suf, l1) << '\n';
  499. // cerr << "-----\n";
  500. }
  501. // cerr << '\n';
  502. resLeft = tr;
  503. // if(resLeft == resRight) {
  504. // cout << "0\n";
  505. // continue;
  506. // }
  507. // cerr << resLeft << " " << resRight << '\n';
  508. // assert(resRight >= resLeft);
  509. // cout << resRight - resLeft + 1 << '\n';
  510. resLeft++;
  511. resRight++;
  512. // assert(l1 <= r1 - r + l);
  513. int pr1 = get(roots[resRight], 0, n, l1, r1 - r + l);
  514. int pr2 = get(roots[resLeft - 1], 0, n, l1, r1 - r + l);
  515. // cerr << pr1 << " " << pr2 << '\n';
  516. // cerr << 1;
  517. writeInt(pr1 - pr2);
  518. writeChar('\n');
  519. // cout << pr1 - pr2 << '\n';
  520.  
  521. }
  522.  
  523. return 0;
  524. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement