ariacas

Untitled

May 13th, 2018
152
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.53 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2.  
  3. using namespace std;
  4.  
  5. #define all(x) (x).begin(), (x).end()
  6. typedef long long ll;
  7.  
  8. inline int nxt() {
  9. int x;
  10. cin >> x;
  11. return x;
  12. }
  13.  
  14. void Build(const string& init, vector<int>& suffArray, vector<int>& lcp) {
  15. string s = init;
  16. s.push_back(char(0));
  17. int n = s.size();
  18. vector<int> head(max(n, 256));
  19. vector<int> color(n);
  20. vector<int> colorSub(n);
  21. vector<int> suffArraySub(n);
  22. lcp.resize(n);
  23. suffArray.resize(n);
  24.  
  25. for (int i = 0; i < s.size(); ++i) {
  26. ++head[s[i]];
  27. }
  28. for (int i = 1; i < 256; ++i) {
  29. head[i] += head[i - 1];
  30. }
  31. for (int i = 255; i > 0; --i) {
  32. head[i] = head[i - 1];
  33. }
  34. head[0] = 0;
  35. for (int i = 0; i < s.size(); ++i) {
  36. suffArray[head[s[i]]] = i;
  37. ++head[s[i]];
  38. }
  39. int numClasses = 1;
  40. head[0] = 0;
  41. for (int i = 1; i < s.size(); ++i) {
  42. if (s[suffArray[i - 1]] != s[suffArray[i]]) {
  43. ++numClasses;
  44. head[numClasses - 1] = i;
  45. }
  46. color[suffArray[i]] = numClasses - 1;
  47. }
  48. for (int k = 1; k < s.size(); k *= 2) {
  49. for (int i = 0; i < s.size(); ++i) {
  50. int first = suffArray[i] - k;
  51. if (first < 0) {
  52. first += s.size();
  53. }
  54. suffArraySub[head[color[first]]] = first;
  55. ++head[color[first]];
  56. }
  57. suffArray = suffArraySub;
  58.  
  59. int second;
  60. pair<int, int> prevClasses, curClasses;
  61. curClasses = { -1, 0 };
  62. numClasses = 0;
  63.  
  64. for (int i = 0; i < s.size(); ++i) {
  65. prevClasses = curClasses;
  66.  
  67. second = suffArray[i] + k;
  68. if (second >= s.size()) {
  69. second -= s.size();
  70. }
  71. curClasses = { color[suffArray[i]], color[second] };
  72.  
  73. if (curClasses != prevClasses) {
  74. ++numClasses;
  75. head[numClasses - 1] = i;
  76. }
  77. colorSub[suffArray[i]] = numClasses - 1;
  78. }
  79.  
  80. color = colorSub;
  81.  
  82. if (numClasses == s.size())
  83. break;
  84. }
  85. vector <int> pos;
  86. int curLcp = 0;
  87. pos.resize(s.size());
  88. for (int i = 0; i < s.size(); ++i) {
  89. pos[suffArray[i]] = i;
  90. }
  91. lcp.resize(s.size());
  92. for (int i = 0; i < s.size(); ++i) {
  93. if (pos[i] == s.size() - 1) {
  94. lcp[pos[i]] = 0;
  95. curLcp = 0;
  96. continue;
  97. }
  98.  
  99. while (s[(i + curLcp) % s.size()] == s[(suffArray[pos[i] + 1] + curLcp) % s.size()]) {
  100. ++curLcp;
  101. }
  102. lcp[pos[i]] = curLcp;
  103.  
  104. --curLcp;
  105. if (curLcp < 0)
  106. curLcp = 0;
  107. }
  108. }
  109.  
  110. void BuildSparseTable(const vector <int>& a, vector < vector <int> >& sparseTable) {
  111. int logSize = 0;
  112. while ((1 << logSize) < a.size()) {
  113. ++logSize;
  114. }
  115. logSize = 19; // <-- THINK HERE!
  116. sparseTable.assign(a.size(), vector <int> (logSize + 1));
  117.  
  118. for (int i = 0; i < a.size(); ++i) {
  119. sparseTable[i][0] = a[i];
  120. }
  121.  
  122. for (int k = 1; k <= logSize; ++k) {
  123. for (int i = 0; i + (1 << k) <= a.size(); ++i) {
  124. sparseTable[i][k] = min(sparseTable[i][k - 1], sparseTable[i + (1 << (k - 1))][k - 1]);
  125. }
  126. }
  127. }
  128.  
  129. int GetMin(int l, int r, const vector < vector <int> >& sparseTable) {
  130. assert(l < r);
  131. int sz = 31 - __builtin_clz(r - l);
  132. return min(sparseTable[l][sz], sparseTable[r - (1 << sz)][sz]);
  133. }
  134.  
  135. pair<int, int> GetGoodInterval(const vector<vector<int>>& sparse, int pos, int x) {
  136. int l = pos, r = (int)sparse.size();
  137. while (r > l + 1) {
  138. int m = (l + r) / 2;
  139. if (GetMin(pos, m + 1, sparse) >= x) {
  140. l = m;
  141. } else {
  142. r = m;
  143. }
  144. }
  145. int ans_r = r;
  146.  
  147. l = 0, r = pos + 1;
  148. while (r > l + 1) {
  149. int m = (l + r) / 2;
  150. if (GetMin(m, pos + 1, sparse) >= x) {
  151. l = m;
  152. } else {
  153. r = m;
  154. }
  155. }
  156. int ans_l = l;
  157.  
  158. return {ans_l, ans_r};
  159. }
  160.  
  161. struct Fenwick {
  162. vector<ll> t;
  163.  
  164. Fenwick() {}
  165.  
  166. Fenwick(int n) : t(n) {
  167. }
  168.  
  169. void add(int pos, ll delta) {
  170. assert(0 <= pos && pos < (int) t.size());
  171. for (int i = pos; i < (int) t.size(); i |= i + 1) {
  172. t[i] += delta;
  173. }
  174. }
  175.  
  176. ll get(int r) {
  177. ll res = 0;
  178. for (int i = r - 1; i >= 0; i = (i & (i + 1)) - 1) {
  179. res += t[i];
  180. }
  181. return res;
  182. }
  183.  
  184. ll get(int l, int r) {
  185. return get(r) - get(l);
  186. }
  187. };
  188.  
  189. struct Kostya {
  190. static constexpr int base = 1 << 18;
  191. vector<int> t[base * 2];
  192. Fenwick fw[base * 2];
  193. vector<int> p;
  194. vector<int> a;
  195.  
  196. int lb(int v, int x, bool check) {
  197. auto it = lower_bound(t[v].begin(), t[v].end(), x);
  198. if (check) {
  199. assert(it != t[v].end() && *it == x);
  200. }
  201. return it - t[v].begin();
  202. }
  203.  
  204. Kostya() {}
  205.  
  206. void init(int n, const vector<int>& p0) {
  207. p = p0;
  208. a.resize(n);
  209. for (int i = 0; i < n; ++i) {
  210. t[i + base] = {p[i]};
  211. fw[i + base] = Fenwick(1);
  212. }
  213. for (int i = base - 1; i > 0; --i) {
  214. set_union(t[i * 2].begin(), t[i * 2].end(), t[i * 2 + 1].begin(), t[i * 2 + 1].end(), back_inserter(t[i]));
  215. fw[i] = Fenwick((int) t[i].size());
  216. }
  217. }
  218.  
  219. void change(int pos, int x) {
  220. int valy = p[pos];
  221. int delta = x - a[pos];
  222. a[pos] += delta;
  223. for (int v = base + pos; v > 0; v /= 2) {
  224. int w = lb(v, valy, true);
  225. fw[v].add(w, delta);
  226. }
  227. }
  228.  
  229. int down_, up_;
  230. int get(int l, int r, int v = 1, int cl = 0, int cr = base) {
  231. if (l <= cl && cr <= r) {
  232. int wr = lb(v, up_, false);
  233. int wl = lb(v, down_, false);
  234. return fw[v].get(wl, wr);
  235. }
  236. if (r <= cl || cr <= l) {
  237. return 0;
  238. }
  239. int cc = (cl + cr) / 2;
  240. return get(l, r, v * 2, cl, cc) + get(l, r, v * 2 + 1, cc, cr);
  241. }
  242.  
  243. int getSum(int l, int r, int down, int up) { // sum{a[x] in [l, r) | down <= x < up}
  244. down_ = down, up_ = up;
  245. return get(l, r);
  246. }
  247. };
  248.  
  249. Kostya zlp;
  250.  
  251. int main() {
  252. string s, t;
  253. cin >> s >> t;
  254.  
  255. reverse(all(s));
  256. reverse(all(t));
  257.  
  258. int n = s.length();
  259. int m = t.length();
  260. vector<int> a(n);
  261. for (int i = 0; i < n; ++i) {
  262. a[i] = nxt();
  263. }
  264. reverse(all(a));
  265.  
  266. vector<int> sa, lcp;
  267. string st = s + "#" + t;
  268. Build(st, sa, lcp);
  269. sa.erase(sa.begin());
  270. lcp.erase(lcp.begin());
  271. vector<int> pos(sa.size());
  272. for (int i = 0; i < (int)sa.size(); ++i) {
  273. pos[sa[i]] = i;
  274. }
  275. vector<vector<int>> sparse;
  276. BuildSparseTable(lcp, sparse);
  277.  
  278. zlp.init(st.size(), sa);
  279. for (int i = 0; i < n; ++i) {
  280. zlp.change(pos[i], a[i]);
  281. }
  282.  
  283. int q = nxt();
  284. while (q--) {
  285. int t = nxt();
  286. if (t == 1) {
  287. int x = nxt(), y = nxt();
  288. zlp.change(pos[n - 1 - x], y);
  289. } else {
  290. int t1 = nxt(), t2 = nxt() + 1, s1 = nxt(), s2 = nxt() + 1;
  291. t1 = m - t1;
  292. t2 = m - t2;
  293. swap(t1, t2);
  294.  
  295. s1 = n - s1;
  296. s2 = n - s2;
  297. swap(s1, s2);
  298.  
  299. if (s2 - s1 < t2 - t1) {
  300. cout << 0 << endl;
  301. continue;
  302. }
  303.  
  304. int idx = pos[t1 + n + 1];
  305. auto seg = GetGoodInterval(sparse, idx, t2 - t1);
  306.  
  307. cout << zlp.getSum(seg.first, seg.second, s1, s2 - t2 + t1) << endl;
  308. }
  309. }
  310.  
  311. return 0;
  312. }
Advertisement
Add Comment
Please, Sign In to add comment