Advertisement
GerONSo

J open nlogn персДО

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