Advertisement
GerONSo

Untitled

Jan 15th, 2019
82
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.08 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 0
  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 pref, l, r, id, tp;
  243. };
  244.  
  245. const int INF = 1e9 + 7;
  246. const int MAXN = 1e6 + 10;
  247. const int BASE = 47;
  248. const int MOD = 1e9 + 7;
  249. const int BASE2 = 43;
  250. const int MOD2 = 998244353ll;
  251.  
  252. vi p(MAXN), cnt(MAXN), c(MAXN);
  253. vi pn(MAXN), cn(MAXN);
  254. vi h, ht, h2, ht2;
  255. vi pows, pows2, tt;
  256. int n;
  257. string t, s;
  258.  
  259. vi get_hash(string s) {
  260. int n = s.size();
  261. vi ans(n + 1);
  262. for(int i = 1; i <= n; i++) {
  263. ans[i] = (ans[i - 1] + s[i - 1] * pows[i - 1]) % MOD;
  264. }
  265. return ans;
  266. }
  267.  
  268. vi get_hash2(string s) {
  269. int n = s.size();
  270. vi ans(n + 1);
  271. for(int i = 1; i <= n; i++) {
  272. ans[i] = (ans[i - 1] + s[i - 1] * pows2[i - 1]) % MOD2;
  273. }
  274. return ans;
  275. }
  276.  
  277. int subhash(int l, int r, vi &h) {
  278. return (((h[r + 1] - h[l] + MOD) % MOD) * pows[n - l - 1]) % MOD;
  279. }
  280.  
  281. int subhash2(int l, int r, vi &h) {
  282. return (((h[r + 1] - h[l] + MOD2) % MOD2) * pows2[n - l - 1]) % MOD2;
  283. }
  284.  
  285. bool compare2(int l1, int r1, int l2, int r2) {
  286. return subhash2(l1, r1, ht2) == subhash2(l2, r2, h2);
  287. }
  288.  
  289. bool compare(int l1, int r1, int l2, int r2) {
  290. return subhash(l1, r1, ht) == subhash(l2, r2, h) && (subhash(l1, r1, ht) == subhash(l2, r2, h)) == compare2(l1, r1, l2, r2);
  291. }
  292.  
  293. bool cmp(node a, node b) {
  294. return a.pref < b.pref;
  295. }
  296.  
  297. void update(int pos, int val) {
  298. while(pos <= n) {
  299. tt[pos] += val;
  300. pos = (pos | (pos - 1)) + 1;
  301. }
  302. }
  303.  
  304. int get(int pos) {
  305. int ans = 0;
  306. while(pos > 0) {
  307. ans += tt[pos];
  308. pos = (pos & (pos - 1));
  309. }
  310. return ans;
  311. }
  312.  
  313. signed main() {
  314. seriy();
  315. cin >> t >> s;
  316. int dn = s.size();
  317. s += t;
  318. s += '$';
  319. n = s.size();
  320.  
  321. int m = t.size();
  322. int mx = max(n, m);
  323. pows.resize(mx);
  324. pows[0] = 1;
  325. pows2.resize(mx);
  326. pows2[0] = 1;
  327. for(int i = 1; i < mx; i++) {
  328. pows[i] = pows[i - 1] * BASE;
  329. pows[i] %= MOD;
  330. pows2[i] = pows2[i - 1] * BASE2;
  331. pows2[i] %= MOD2;
  332. }
  333. h = get_hash(s);
  334. ht = get_hash(t);
  335. h2 = get_hash2(s);
  336. ht2 = get_hash2(t);
  337. for(int i = 0; i < n; i++) {
  338. cnt[s[i]]++;
  339. }
  340. for(int i = 1; i < MAXN; i++) {
  341. cnt[i] += cnt[i - 1];
  342. }
  343. for(int i = 0; i < n; i++) {
  344. p[--cnt[s[i]]] = i;
  345. }
  346. c[p[0]] = 0;
  347. int cur = 1;
  348. for(int i = 1; i < n; i++) {
  349. if (s[p[i]] != s[p[i - 1]]) {
  350. ++cur;
  351. }
  352. c[p[i]] = cur - 1;
  353. }
  354.  
  355. for(int h = 0; (1 << h) < n; ++h) {
  356. for(int i = 0; i < n; i++) {
  357. pn[i] = (p[i] + n - (1 << h)) % n;
  358. }
  359. cnt.assign(MAXN, 0);
  360. for(int i = 0; i < n; i++) {
  361. cnt[c[pn[i]]]++;
  362. }
  363. for(int i = 1; i < cur; i++) {
  364. cnt[i] += cnt[i - 1];
  365. }
  366. for(int i = n - 1; i >= 0; i--) {
  367. p[--cnt[c[pn[i]]]] = pn[i];
  368. }
  369. cn[p[0]] = 0;
  370. cur = 1;
  371. for(int i = 1; i < n; i++) {
  372. int m1 = (p[i] + (1 << h)) % n, m2 = (p[i - 1] + (1 << h)) % n;
  373. if (c[p[i]] != c[p[i - 1]] || c[m1] != c[m2]) {
  374. cur++;
  375. }
  376. cn[p[i]] = cur - 1;
  377. }
  378. c = cn;
  379. }
  380. n--;
  381. for(int i = 0; i < n; i++) {
  382. p[i] = p[i + 1];
  383. }
  384. vi rp(n);
  385. for(int i = 0; i < n; i++) {
  386. rp[p[i]] = i;
  387. }
  388. tt.resize(MAXN);
  389. vector<node> rq;
  390. int q;
  391. cin >> q;
  392. vi ans(q);
  393. for(int i = 0; i < q; i++) {
  394. int l, r, l1, r1;
  395. cin >> l >> r >> l1 >> r1;
  396. l--;
  397. r--;
  398. l1--;
  399. r1--;
  400. if(r - l > r1 - l1) {
  401. ans[i] = 0;
  402. continue;
  403. }
  404. if(n == 1) {
  405. if(r == l) {
  406. if(t[l] == s[l1]) {
  407. ans[i] = 1;
  408. }
  409. else {
  410. ans[i] = 0;
  411. }
  412. }
  413. else {
  414. ans[i] = 0;
  415. }
  416. continue;
  417. }
  418. int resLeft, resRight;
  419. int tl = rp[dn + l], tr = n;
  420. while(tr - tl > 1) {
  421. int mid = (tr + tl) >> 1;
  422. int suf = p[mid];
  423. if(n - suf < r - l + 1) {
  424. tr = mid;
  425. }
  426. else if(compare(l, r, suf, suf + r - l)) {
  427. tl = mid;
  428. }
  429. else {
  430. tr = mid;
  431. }
  432. }
  433. resRight = tl;
  434. tl = -1, tr = rp[dn + l];
  435. while(tr - tl > 1) {
  436. int mid = (tl + tr) >> 1;
  437. int suf = p[mid];
  438. if(n - suf < r - l + 1) {
  439. tl = mid;
  440. }
  441. else if(compare(l, r, suf, suf + r - l)) {
  442. tr = mid;
  443. }
  444. else {
  445. tl = mid;
  446. }
  447. }
  448. resLeft = tr;
  449. resRight++;
  450. rq.pb({resLeft, l1, r1 - r + l, i, -1});
  451. rq.pb({resRight, l1, r1 - r + l, i, 1});
  452. // int pr1 = get(roots[resRight], 0, n, l1, r1 - r + l);
  453. // int pr2 = get(roots[resLeft - 1], 0, n, l1, r1 - r + l);
  454. // writeInt(pr1 - pr2);
  455. // writeChar('\n');
  456. }
  457.  
  458. sort(all(rq), cmp);
  459. int cur_ver = 0;
  460. for(int i = 0; i < rq.size(); i++) {
  461. // cerr << rq[i].pref << " " << rq[i].l << " " << rq[i].r << " " << rq[i].id << '\n';
  462. while(cur_ver < rq[i].pref) {
  463. cur_ver++;
  464. // cerr << p[cur_ver - 1] << " +1 " << '\n';
  465. update(p[cur_ver - 1] + 1, 1);
  466. }
  467. ans[rq[i].id] += rq[i].tp * (get(rq[i].r + 1) - get(rq[i].l));
  468. }
  469. for(auto i : ans) {
  470. cout << i << '\n';
  471. }
  472. return 0;
  473. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement