Advertisement
GerONSo

J open 60

Jan 8th, 2019
264
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.90 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. struct node {
  69. int sum;
  70. node *left;
  71. node *right;
  72. };
  73.  
  74. const int MAXN = 1e6 + 10;
  75. const int BASE = 47;
  76. const int MOD = 1e9 + 7;
  77.  
  78. vi p(MAXN), cnt(MAXN), c(MAXN);
  79. vi pn(MAXN), cn(MAXN);
  80. vi h, ht;
  81. vi pows;
  82. int n;
  83. string t, s;
  84.  
  85. void build(node *&v, int tl, int tr, int pos) {
  86. if(tl == tr) {
  87. if(tl == pos) v -> sum = 1;
  88. return;
  89. }
  90. int tm = (tl + tr) >> 1;
  91. v -> left = new node();
  92. v -> right = new node();
  93. build(v -> left, tl, tm, pos);
  94. build(v -> right, tm + 1, tr, pos);
  95. v -> sum = v -> left -> sum + v -> right -> sum;
  96. }
  97.  
  98. int get(node *&v, int tl, int tr, int l, int r) {
  99. if(tl > r || tr < l) {
  100. return 0;
  101. }
  102. if(tl >= l && tr <= r) {
  103. return v -> sum;
  104. }
  105. int tm = (tl + tr) >> 1;
  106. int left = get(v -> left, tl, tm, l, r);
  107. int right = get(v -> right, tm + 1, tr, l, r);
  108. return left + right;
  109. }
  110.  
  111. void update(node *&v, node *&v2, int tl, int tr, int pos) {
  112. // cerr << tl << " " << tr << '\n';
  113. if(tl > pos || tr < pos) {
  114. return;
  115. }
  116. if(tl == tr) {
  117. (v -> sum)++;
  118. // cerr << tl << " " << tr << " " << v -> sum << '\n';
  119. return;
  120. }
  121. int tm = (tl + tr) >> 1;
  122. if(pos > tm) {
  123. v -> left = v2 -> left;
  124. v -> right = new node();
  125. update(v -> right, v2 -> right, tm + 1, tr, pos);
  126. }
  127. else {
  128. v -> right = v2 -> right;
  129. v -> left = new node();
  130. update(v -> left, v2 -> left, tl, tm, pos);
  131. }
  132. v -> sum = v -> left -> sum + v -> right -> sum;
  133. // cerr << tl << " " << tr << " " << v -> sum << '\n';
  134. }
  135.  
  136. vi get_hash(string s) {
  137. int n = s.size();
  138. vi ans(n + 1);
  139. for(int i = 1; i <= n; i++) {
  140. ans[i] = (ans[i - 1] + s[i - 1] * pows[i - 1]) % MOD;
  141. }
  142. return ans;
  143. }
  144.  
  145. int subhash(int l, int r, vi &h) {
  146. return (((h[r + 1] - h[l] + MOD) % MOD) * pows[n - l - 1]) % MOD;
  147. }
  148.  
  149. bool compare(int l1, int r1, int l2, int r2) {
  150. return subhash(l1, r1, ht) == subhash(l2, r2, h);
  151. }
  152.  
  153. bool compare2(int l, int r, int suf, int r2) {
  154. int ttl = 0, ttr = min(n - suf, r - l + 1) + 1;
  155. while(ttr - ttl > 1) {
  156. int mid2 = (ttl + ttr) >> 1;
  157. if(compare(l, l + mid2 - 1, suf, suf + mid2 - 1)) {
  158. ttl = mid2;
  159. }
  160. else {
  161. ttr = mid2;
  162. }
  163. }
  164. // cerr << ttl << " " << suf << '\n';
  165. if(ttl == min(n - suf, r - l + 1)) {
  166. return n - suf < r - l + 1;
  167. }
  168. else {
  169. return s[suf + ttl] < t[l + ttl];
  170. }
  171. }
  172.  
  173.  
  174. bool compare3(int l, int r, int suf, int r2) {
  175. int ttl = 0, ttr = min(n - suf, r - l + 1) + 1;
  176. while(ttr - ttl > 1) {
  177. int mid2 = (ttl + ttr) >> 1;
  178. if(compare(l, l + mid2 - 1, suf, suf + mid2 - 1)) {
  179. ttl = mid2;
  180. }
  181. else {
  182. ttr = mid2;
  183. }
  184. }
  185. // cerr << ttl << " " << suf << '\n';
  186. if(ttl == min(n - suf, r - l + 1)) {
  187. return 1;
  188. }
  189. else {
  190. return s[suf + ttl] < t[l + ttl];
  191. }
  192. }
  193.  
  194. signed main() {
  195. seriy();
  196.  
  197. cin >> t >> s;
  198. s += '$';
  199. n = s.size();
  200. int dn = n;
  201. int m = t.size();
  202. int mx = max(n, m);
  203. pows.resize(mx);
  204. pows[0] = 1;
  205. for(int i = 1; i < mx; i++) {
  206. pows[i] = pows[i - 1] * BASE;
  207. pows[i] %= MOD;
  208. }
  209. h = get_hash(s);
  210. ht = get_hash(t);
  211. for(int i = 0; i < n; i++) {
  212. cnt[s[i]]++;
  213. }
  214. for(int i = 1; i < MAXN; i++) {
  215. cnt[i] += cnt[i - 1];
  216. }
  217. for(int i = 0; i < n; i++) {
  218. p[--cnt[s[i]]] = i;
  219. }
  220. c[p[0]] = 0;
  221. int cur = 1;
  222. for(int i = 1; i < n; i++) {
  223. if (s[p[i]] != s[p[i - 1]]) {
  224. ++cur;
  225. }
  226. c[p[i]] = cur - 1;
  227. }
  228.  
  229. for(int h = 0; (1 << h) < n; ++h) {
  230. for(int i = 0; i < n; i++) {
  231. pn[i] = (p[i] + n - (1 << h)) % n;
  232. }
  233. cnt.assign(MAXN, 0);
  234. for(int i = 0; i < n; i++) {
  235. cnt[c[pn[i]]]++;
  236. }
  237. for(int i = 1; i < cur; i++) {
  238. cnt[i] += cnt[i - 1];
  239. }
  240. for(int i = n - 1; i >= 0; i--) {
  241. p[--cnt[c[pn[i]]]] = pn[i];
  242. }
  243. cn[p[0]] = 0;
  244. cur = 1;
  245. for(int i = 1; i < n; i++) {
  246. int m1 = (p[i] + (1 << h)) % n, m2 = (p[i - 1] + (1 << h)) % n;
  247. if (c[p[i]] != c[p[i - 1]] || c[m1] != c[m2]) {
  248. cur++;
  249. }
  250. cn[p[i]] = cur - 1;
  251. }
  252. c = cn;
  253. }
  254. n--;
  255. for(int i = 0; i < n; i++) {
  256. p[i] = p[i + 1];
  257. }
  258. vector<node*> roots(n + 1);
  259. roots[0] = new node();
  260. build(roots[0], 0, n, p[0]);
  261. for(int i = 1; i < n; i++) {
  262. roots[i] = new node();
  263. update(roots[i], roots[i - 1], 0, n, p[i]);
  264. }
  265. // cerr << compare3(0, 1, p[0], 6);
  266. // cerr << "-------\n";
  267. int q;
  268. cin >> q;
  269. while(q--) {
  270. int l, r, l1, r1;
  271. cin >> l >> r >> l1 >> r1;
  272. l--;
  273. r--;
  274. l1--;
  275. r1--;
  276. if(r - l > r1 - l1) {
  277. cout << "0\n";
  278. continue;
  279. }
  280. if(n == 1) {
  281. if(r == l) {
  282. if(t[l] == s[l1]) {
  283. cout << "1\n";
  284. }
  285. else {
  286. cout << "0\n";
  287. }
  288. }
  289. else {
  290. cout << "0\n";
  291. }
  292. continue;
  293. }
  294. // cerr << p[n - 1] << '\n';
  295. bool c1 = compare2(l, r, p[n - 1], r1);
  296. if(c1) {
  297. cout << "0\n";
  298. continue;
  299. }
  300. bool c2 = compare3(l, r, p[0], r1);
  301. if(!c2) {
  302. cout << "0\n";
  303. continue;
  304. }
  305. int resLeft, resRight;
  306. int tl = -1, tr = n - 1;
  307. while(tr - tl > 1) {
  308. int mid = (tr + tl) >> 1;
  309. int suf = p[mid];
  310.  
  311. if(compare2(l, r, suf, r1)) {
  312. tl = mid;
  313. }
  314. else {
  315. tr = mid;
  316. }
  317. // cerr << mid << " !" << '\n';
  318. // cerr << mid << " " << compare2(l, r, suf, r1) << '\n';
  319. // cerr << "------\n";
  320. }
  321.  
  322. resLeft = tr;
  323. tl = 0, tr = n;
  324. while(tr - tl > 1) {
  325. int mid = (tl + tr) >> 1;
  326. int suf = p[mid];
  327.  
  328. if(compare3(l, r, suf, l1)) {
  329. tl = mid;
  330. }
  331. else {
  332. tr = mid;
  333. }
  334. // cerr << '\n';
  335. // cerr << mid << " !" << '\n';
  336.  
  337. // cerr << mid << " " << compare3(l, r, suf, l1) << '\n';
  338. // cerr << "-----\n";
  339. }
  340. // cerr << '\n';
  341. resRight = tl;
  342. // cerr << resLeft << " " << resRight << '\n';
  343. if(resLeft > resRight) {
  344. cout << "0\n";
  345. continue;
  346. }
  347. // assert(resRight >= resLeft);
  348. // cout << resRight - resLeft + 1 << '\n';
  349. int pr1 = 0;
  350. if(r1 - r + l >= l1) pr1 = get(roots[resRight], 0, n, l1, r1 - r + l);
  351. int pr2 = 0;
  352. if(r1 - r + l >= l1 && resLeft > 0) pr2 = get(roots[resLeft - 1], 0, n, l1, r1 - r + l);
  353. // cerr << pr1 << " " << pr2 << '\n';
  354. // cerr << 1;
  355. cout << pr1 - pr2 << '\n';
  356.  
  357. }
  358.  
  359. return 0;
  360. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement