Advertisement
Guest User

Untitled

a guest
Apr 2nd, 2020
176
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.83 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. #include <ext/pb_ds/assoc_container.hpp>
  3. #include <ext/pb_ds/tree_policy.hpp>
  4.  
  5. using namespace std;
  6. using namespace __gnu_pbds;
  7.  
  8. typedef long long ll;
  9. typedef pair<int, int> pii;
  10. #define all(x) (x).begin(), (x).end()
  11. #define fap(x) cerr << __LINE__ << " says: " << #x << " = " << x << "\n"
  12. #define FastIO ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
  13. const int inf = 0x3f3f3f3f;
  14. const ll INF = 2e18;
  15.  
  16. /*
  17. Order Statistics Tree ( OST )
  18.  
  19. find_by_order()
  20. takes an integer k and returns an iterator to the k'th largest element counting from zero
  21. order_of_key()
  22. takes an element, here an integer and returns the number of elements strictly smaller than input
  23. */
  24.  
  25. typedef tree<
  26. int,
  27. null_type,
  28. less<int>,
  29. rb_tree_tag,
  30. tree_order_statistics_node_update>
  31. ordered_set;
  32.  
  33. const int N = 2e5 + 7;
  34.  
  35. namespace SQ {
  36. const int BLOCK = 450;
  37. list<pii> seq[BLOCK];
  38. int active[BLOCK];
  39.  
  40. void init() {
  41. for(int i=0; i<BLOCK; ++i) {
  42. active[i] = 0;
  43. seq[i].clear();
  44. }
  45. active[0] = 1;
  46. seq[0].push_back(pii(1, inf));
  47. }
  48.  
  49. void insert(int pos, int id) {
  50. int which = -1;
  51. for(int i=0; i<BLOCK; ++i) {
  52. if(active[i] >= pos) {
  53. which = i;
  54. break;
  55. }
  56. pos -= active[i];
  57. }
  58.  
  59. assert(which > -1);
  60. for(auto it = seq[which].begin(); it != seq[which].end(); ++it) {
  61. pos -= it->first;
  62. if(pos <= 0) {
  63. seq[which].insert(it, pii(1, id));
  64. ++active[which];
  65. break;
  66. }
  67. }
  68.  
  69. for(int i=which; i+1 < BLOCK and (int) seq[i].size() > BLOCK; ++i) {
  70. pii qq = seq[i].back();
  71. seq[i].pop_back();
  72. active[i] -= qq.first;
  73. seq[i+1].push_front(qq);
  74. active[i+1] += qq.first;
  75. }
  76. }
  77.  
  78. void erase(int pos) {
  79. int which = -1;
  80. for(int i=0; i<BLOCK; ++i) {
  81. if(active[i] >= pos) {
  82. which = i;
  83. break;
  84. }
  85. pos -= active[i];
  86. }
  87.  
  88. assert(which > -1);
  89. for(auto it = seq[which].begin(); it != seq[which].end(); ++it) {
  90. pos -= it->first;
  91. if(pos <= 0 and it->first) {
  92. it->first = 0;
  93. --active[which];
  94. break;
  95. }
  96. }
  97. }
  98.  
  99. vector<int> get_seq() {
  100. vector<int> ret;
  101. for(int i=0; i<BLOCK; ++i) {
  102. if(seq[i].empty()) break;
  103. for(auto qq : seq[i]) {
  104. ret.push_back(qq.second);
  105. }
  106. }
  107. if(!ret.empty() and ret.back() == inf) ret.pop_back();
  108. return ret;
  109. }
  110.  
  111. void prnt() {
  112. for(int i=0; i<BLOCK; ++i) {
  113. if(seq[i].empty()) break;
  114. if(!active[i]) continue;
  115. for(auto qq : seq[i]) {
  116. if(qq.first and qq.second < inf) cout << qq.second << " ";
  117. }
  118. }
  119. cout << " -- |\n";
  120. }
  121. };
  122.  
  123. namespace SegTree {
  124. struct dat {
  125. int sum, lsum, rsum, best;
  126. int negcnt, max_neg;
  127.  
  128. dat(int val = 0) {
  129. sum = lsum = rsum = best = val;
  130. negcnt = (val < 0);
  131. max_neg = (val < 0 ? val : -inf);
  132. }
  133. dat operator + (const dat &p) {
  134. dat ret;
  135. ret.sum = sum + p.sum;
  136. ret.lsum = max(lsum, sum + p.lsum);
  137. ret.rsum = max(rsum + p.sum, p.rsum);
  138. ret.best = max(max(best, p.best), rsum + p.lsum);
  139. ret.negcnt = negcnt + p.negcnt;
  140. ret.max_neg = max(max_neg, p.max_neg);
  141. return ret;
  142. }
  143. } tr[4*N];
  144.  
  145. void update(int at, int l, int r, int pos, int val) {
  146. if(l == r) {
  147. tr[at] = dat(val);
  148. // cerr << l << " " << r << ": " << tr[at].best << " " << tr[at].lsum << " " << tr[at].rsum << " " << tr[at].sum << "\n";
  149. return ;
  150. }
  151.  
  152. int lc = (at << 1), rc = ((at << 1) ^ 1), mid = ((l + r) >> 1);
  153. if(pos <= mid) update(lc, l, mid, pos, val);
  154. else update(rc, mid + 1, r, pos, val);
  155.  
  156. tr[at] = tr[lc] + tr[rc];
  157. // cerr << l << " " << r << ": " << tr[at].best << " " << tr[at].lsum << " " << tr[at].rsum << " " << tr[at].sum << "\n";
  158. }
  159.  
  160. dat query(int at, int l, int r, int lo, int hi) {
  161. if(l > hi or r < lo) return dat(0);
  162. if(l >= lo and r <= hi) return tr[at];
  163.  
  164. int lc = (at << 1), rc = ((at << 1) ^ 1), mid = ((l + r) >> 1);
  165. dat q1 = query(lc, l, mid, lo, hi);
  166. dat q2 = query(rc, mid + 1, r, lo, hi);
  167. return q1 + q2;
  168. }
  169. };
  170.  
  171. struct Query {
  172. char op;
  173. int x, y;
  174. } qu[N];
  175.  
  176. int a[N];
  177. int aidx[N], qidx[N]; // array and query element position in new arr
  178.  
  179. void precal(int n, int q) {
  180. SQ::init();
  181.  
  182. for(int i=1; i<=n; ++i) SQ::insert(i, i);
  183. for(int i=1; i<=q; ++i) {
  184. if(qu[i].op == 'I') SQ::insert(qu[i].x, -i);
  185. else if(qu[i].op == 'D') SQ::erase(qu[i].x);
  186. }
  187.  
  188. vector<int> v = SQ::get_seq();
  189. for(int i=0; i<(int) v.size(); ++i) {
  190. if(v[i] > 0) aidx[v[i]] = i + 1;
  191. else qidx[-v[i]] = i + 1;
  192. }
  193. }
  194.  
  195. void prnt(ordered_set &ost) {
  196. for(auto qq : ost) cerr << qq << " ";
  197. cerr << " -- - OST\n";
  198. }
  199.  
  200. int main() {
  201. FastIO;
  202.  
  203. int n;
  204. cin >> n;
  205. for(int i=1; i<=n; ++i) cin >> a[i];
  206.  
  207. int q;
  208. cin >> q;
  209. for(int i=1; i<=q; ++i) {
  210. cin >> qu[i].op >> qu[i].x;
  211. if(qu[i].op != 'D') cin >> qu[i].y;
  212. if(qu[i].op == 'Q' and qu[i].x > qu[i].y) swap(qu[i].x, qu[i].y);
  213. }
  214.  
  215. precal(n, q);
  216.  
  217. int nn = n + q;
  218. ordered_set ost;
  219. for(int i=1; i<=n; ++i) {
  220. ost.insert(aidx[i]);
  221. SegTree::update(1, 1, nn, aidx[i], a[i]);
  222.  
  223. }
  224. // prnt(ost);
  225.  
  226. for(int i=1; i<=q; ++i) {
  227. if(qu[i].op == 'I') {
  228. ost.insert(qidx[i]);
  229. SegTree::update(1, 1, nn, qidx[i], qu[i].y);
  230. }
  231. else if(qu[i].op == 'D') {
  232. auto it = ost.find_by_order(qu[i].x - 1);
  233. assert(it != ost.end());
  234. SegTree::update(1, 1, nn, *it, 0);
  235. ost.erase(it);
  236. }
  237. else if(qu[i].op == 'R') {
  238. auto it = ost.find_by_order(qu[i].x - 1);
  239. assert(it != ost.end());
  240. SegTree::update(1, 1, nn, *it, qu[i].y);
  241. }
  242. else {
  243. auto lit = ost.find_by_order(qu[i].x - 1);
  244. auto rit = ost.find_by_order(qu[i].y - 1);
  245. assert(lit != ost.end() and rit != ost.end());
  246.  
  247. auto temp = SegTree::query(1, 1, nn, *lit, *rit);
  248. int len = qu[i].y - qu[i].x + 1;
  249. int res;
  250. if(temp.negcnt == len) res = temp.max_neg;
  251. else res = temp.best;
  252. cout << res << "\n";
  253. }
  254. // prnt(ost);
  255. }
  256.  
  257. return 0;
  258. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement