fork download
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3.  
  4. struct Fenwick {
  5. int n = 0;
  6. vector<int> bit;
  7.  
  8. void build(const vector<int>& a) {
  9. n = (int)a.size();
  10. bit.assign(n + 1, 0);
  11.  
  12. for (int i = 0; i < n; ++i) {
  13. bit[i + 1] += a[i];
  14.  
  15. int parent = i + 1 + ((i + 1) & -(i + 1));
  16. if (parent <= n) {
  17. bit[parent] += bit[i + 1];
  18. }
  19. }
  20. }
  21.  
  22. void add(int index, int value) {
  23. for (int i = index + 1; i <= n; i += i & -i) {
  24. bit[i] += value;
  25. }
  26. }
  27.  
  28. // Tổng kích thước các block có chỉ số < index.
  29. int prefixBefore(int index) const {
  30. int result = 0;
  31.  
  32. for (int i = index; i > 0; i -= i & -i) {
  33. result += bit[i];
  34. }
  35.  
  36. return result;
  37. }
  38.  
  39. // Trả về block chứa phần tử thứ k, với k đánh số từ 1.
  40. int kth(int k) const {
  41. int index = 0;
  42. int currentSum = 0;
  43.  
  44. int step = 1;
  45. while ((step << 1) <= n) {
  46. step <<= 1;
  47. }
  48.  
  49. for (; step > 0; step >>= 1) {
  50. int nextIndex = index + step;
  51.  
  52. if (nextIndex <= n &&
  53. currentSum + bit[nextIndex] < k) {
  54. index = nextIndex;
  55. currentSum += bit[nextIndex];
  56. }
  57. }
  58.  
  59. return index;
  60. }
  61. };
  62.  
  63. struct DynamicOrder {
  64. static constexpr int BLOCK_SIZE = 128;
  65.  
  66. struct Block {
  67. vector<int> elements;
  68. int order = -1;
  69. };
  70.  
  71. int n;
  72.  
  73. vector<Block*> blocks;
  74. vector<Block*> owner;
  75. vector<int> positionInBlock;
  76.  
  77. Fenwick fenwick;
  78.  
  79. DynamicOrder(const vector<int>& sequence, int numberOfElements)
  80. : n(numberOfElements),
  81. owner(n + 1),
  82. positionInBlock(n + 1) {
  83. for (int left = 0; left < n; left += BLOCK_SIZE) {
  84. int right = min(n, left + BLOCK_SIZE);
  85.  
  86. Block* block = new Block();
  87. block->elements.reserve(2 * BLOCK_SIZE + 1);
  88.  
  89. for (int i = left; i < right; ++i) {
  90. int value = sequence[i];
  91.  
  92. owner[value] = block;
  93. positionInBlock[value] =
  94. (int)block->elements.size();
  95.  
  96. block->elements.push_back(value);
  97. }
  98.  
  99. block->order = (int)blocks.size();
  100. blocks.push_back(block);
  101. }
  102.  
  103. rebuildFenwick();
  104. }
  105.  
  106. ~DynamicOrder() {
  107. for (Block* block : blocks) {
  108. delete block;
  109. }
  110. }
  111.  
  112. void rebuildFenwick() {
  113. vector<int> sizes(blocks.size());
  114.  
  115. for (int i = 0; i < (int)blocks.size(); ++i) {
  116. blocks[i]->order = i;
  117. sizes[i] = (int)blocks[i]->elements.size();
  118. }
  119.  
  120. fenwick.build(sizes);
  121. }
  122.  
  123. // true khi hạng an toàn của x nhỏ hơn hạng của y.
  124. bool before(int x, int y) const {
  125. if (owner[x] == owner[y]) {
  126. return positionInBlock[x] < positionInBlock[y];
  127. }
  128.  
  129. return owner[x]->order < owner[y]->order;
  130. }
  131.  
  132. // Phần tử có hạng lớn hơn, tức kém an toàn hơn.
  133. int later(int x, int y) const {
  134. if (x == -1) {
  135. return y;
  136. }
  137.  
  138. if (y == -1) {
  139. return x;
  140. }
  141.  
  142. return before(x, y) ? y : x;
  143. }
  144.  
  145. bool atLeast(int x, int threshold) const {
  146. return !before(x, threshold);
  147. }
  148.  
  149. void eraseFromBlock(Block* block, int index) {
  150. block->elements.erase(block->elements.begin() + index);
  151.  
  152. for (int i = index;
  153. i < (int)block->elements.size();
  154. ++i) {
  155. positionInBlock[block->elements[i]] = i;
  156. }
  157. }
  158.  
  159. void insertIntoBlock(Block* block, int index, int value) {
  160. block->elements.insert(
  161. block->elements.begin() + index,
  162. value
  163. );
  164.  
  165. for (int i = index;
  166. i < (int)block->elements.size();
  167. ++i) {
  168. int element = block->elements[i];
  169.  
  170. owner[element] = block;
  171. positionInBlock[element] = i;
  172. }
  173. }
  174.  
  175. void splitIfNeeded(Block* block) {
  176. if ((int)block->elements.size() <=
  177. 2 * BLOCK_SIZE) {
  178. return;
  179. }
  180.  
  181. int blockIndex = block->order;
  182. int middle = (int)block->elements.size() / 2;
  183.  
  184. Block* newBlock = new Block();
  185. newBlock->elements.reserve(2 * BLOCK_SIZE + 1);
  186.  
  187. newBlock->elements.assign(
  188. block->elements.begin() + middle,
  189. block->elements.end()
  190. );
  191.  
  192. block->elements.erase(
  193. block->elements.begin() + middle,
  194. block->elements.end()
  195. );
  196.  
  197. for (int i = 0;
  198. i < (int)newBlock->elements.size();
  199. ++i) {
  200. int element = newBlock->elements[i];
  201.  
  202. owner[element] = newBlock;
  203. positionInBlock[element] = i;
  204. }
  205.  
  206. blocks.insert(
  207. blocks.begin() + blockIndex + 1,
  208. newBlock
  209. );
  210.  
  211. rebuildFenwick();
  212. }
  213.  
  214. // Đưa x tới hạng rank, rank đánh số từ 1.
  215. void moveToRank(int x, int rank) {
  216. Block* sourceBlock = owner[x];
  217. int sourceBlockIndex = sourceBlock->order;
  218. int sourcePosition = positionInBlock[x];
  219.  
  220. eraseFromBlock(sourceBlock, sourcePosition);
  221. fenwick.add(sourceBlockIndex, -1);
  222.  
  223. int targetBlockIndex = fenwick.kth(rank);
  224. int elementsBefore =
  225. fenwick.prefixBefore(targetBlockIndex);
  226.  
  227. int targetPosition =
  228. rank - elementsBefore - 1;
  229.  
  230. Block* targetBlock = blocks[targetBlockIndex];
  231.  
  232. insertIntoBlock(
  233. targetBlock,
  234. targetPosition,
  235. x
  236. );
  237.  
  238. fenwick.add(targetBlockIndex, 1);
  239.  
  240. splitIfNeeded(targetBlock);
  241. }
  242. };
  243.  
  244. struct SegmentTree {
  245. int n;
  246. int size;
  247.  
  248. vector<int> tree;
  249. DynamicOrder* order;
  250.  
  251. SegmentTree(int numberOfPositions, DynamicOrder* orderStructure)
  252. : n(numberOfPositions), order(orderStructure) {
  253. size = 1;
  254.  
  255. while (size < n) {
  256. size <<= 1;
  257. }
  258.  
  259. tree.assign(size << 1, -1);
  260.  
  261. for (int i = 1; i <= n; ++i) {
  262. tree[size + i - 1] = i;
  263. }
  264.  
  265. for (int node = size - 1; node >= 1; --node) {
  266. tree[node] = order->later(
  267. tree[node << 1],
  268. tree[node << 1 | 1]
  269. );
  270. }
  271. }
  272.  
  273. void refresh(int position) {
  274. int node = size + position - 1;
  275.  
  276. for (node >>= 1; node > 0; node >>= 1) {
  277. tree[node] = order->later(
  278. tree[node << 1],
  279. tree[node << 1 | 1]
  280. );
  281. }
  282. }
  283.  
  284. int rangeMaximum(int left, int right) const {
  285. int leftResult = -1;
  286. int rightResult = -1;
  287.  
  288. int l = size + left - 1;
  289. int r = size + right - 1;
  290.  
  291. while (l <= r) {
  292. if (l & 1) {
  293. leftResult =
  294. order->later(leftResult, tree[l]);
  295. ++l;
  296. }
  297.  
  298. if (!(r & 1)) {
  299. rightResult =
  300. order->later(tree[r], rightResult);
  301. --r;
  302. }
  303.  
  304. l >>= 1;
  305. r >>= 1;
  306. }
  307.  
  308. return order->later(leftResult, rightResult);
  309. }
  310.  
  311. int findLastRecursive(
  312. int node,
  313. int nodeLeft,
  314. int nodeRight,
  315. int queryLeft,
  316. int queryRight,
  317. int threshold
  318. ) const {
  319. if (nodeRight < queryLeft ||
  320. queryRight < nodeLeft ||
  321. tree[node] == -1 ||
  322. !order->atLeast(tree[node], threshold)) {
  323. return -1;
  324. }
  325.  
  326. if (nodeLeft == nodeRight) {
  327. return nodeLeft;
  328. }
  329.  
  330. int middle = (nodeLeft + nodeRight) >> 1;
  331.  
  332. int result = findLastRecursive(
  333. node << 1 | 1,
  334. middle + 1,
  335. nodeRight,
  336. queryLeft,
  337. queryRight,
  338. threshold
  339. );
  340.  
  341. if (result != -1) {
  342. return result;
  343. }
  344.  
  345. return findLastRecursive(
  346. node << 1,
  347. nodeLeft,
  348. middle,
  349. queryLeft,
  350. queryRight,
  351. threshold
  352. );
  353. }
  354.  
  355. int findFirstRecursive(
  356. int node,
  357. int nodeLeft,
  358. int nodeRight,
  359. int queryLeft,
  360. int queryRight,
  361. int threshold
  362. ) const {
  363. if (nodeRight < queryLeft ||
  364. queryRight < nodeLeft ||
  365. tree[node] == -1 ||
  366. !order->atLeast(tree[node], threshold)) {
  367. return -1;
  368. }
  369.  
  370. if (nodeLeft == nodeRight) {
  371. return nodeLeft;
  372. }
  373.  
  374. int middle = (nodeLeft + nodeRight) >> 1;
  375.  
  376. int result = findFirstRecursive(
  377. node << 1,
  378. nodeLeft,
  379. middle,
  380. queryLeft,
  381. queryRight,
  382. threshold
  383. );
  384.  
  385. if (result != -1) {
  386. return result;
  387. }
  388.  
  389. return findFirstRecursive(
  390. node << 1 | 1,
  391. middle + 1,
  392. nodeRight,
  393. queryLeft,
  394. queryRight,
  395. threshold
  396. );
  397. }
  398.  
  399. int findLast(
  400. int left,
  401. int right,
  402. int threshold
  403. ) const {
  404. if (left > right) {
  405. return -1;
  406. }
  407.  
  408. return findLastRecursive(
  409. 1,
  410. 1,
  411. size,
  412. left,
  413. right,
  414. threshold
  415. );
  416. }
  417.  
  418. int findFirst(
  419. int left,
  420. int right,
  421. int threshold
  422. ) const {
  423. if (left > right) {
  424. return -1;
  425. }
  426.  
  427. return findFirstRecursive(
  428. 1,
  429. 1,
  430. size,
  431. left,
  432. right,
  433. threshold
  434. );
  435. }
  436. };
  437.  
  438. int main() {
  439. ios::sync_with_stdio(false);
  440. cin.tie(nullptr);
  441.  
  442. freopen("vi.INP" , "r" , stdin);
  443. freopen("vi.OUT" , "w" , stdout);
  444.  
  445. int subtask;
  446. cin >> subtask;
  447.  
  448. int n, q, favourite;
  449. cin >> n >> q >> favourite;
  450.  
  451. vector<int> safety(n + 1);
  452. vector<int> positionAtRank(n);
  453.  
  454. for (int position = 1; position <= n; ++position) {
  455. cin >> safety[position];
  456. positionAtRank[safety[position] - 1] = position;
  457. }
  458.  
  459. DynamicOrder order(positionAtRank, n);
  460. SegmentTree segmentTree(n, &order);
  461.  
  462. while (q--) {
  463. char type;
  464. cin >> type;
  465.  
  466. if (type == 'U') {
  467. int position, newRank;
  468. cin >> position >> newRank;
  469.  
  470. /*
  471.   Sau cập nhật, quan hệ thứ tự giữa mọi cặp vị trí
  472.   không chứa position vẫn giữ nguyên. Vì vậy chỉ cần
  473.   cập nhật đường đi của position trên segment tree.
  474.   */
  475. order.moveToRank(position, newRank);
  476. segmentTree.refresh(position);
  477. } else {
  478. int position;
  479. cin >> position;
  480.  
  481. if (position == favourite) {
  482. cout << 1 << '\n';
  483. continue;
  484. }
  485.  
  486. if (position > favourite) {
  487. /*
  488.   Hạng lớn nhất trên đoạn từ favourite + 1
  489.   tới position.
  490.   */
  491. int threshold = segmentTree.rangeMaximum(
  492. favourite + 1,
  493. position
  494. );
  495.  
  496. /*
  497.   Vị trí gần favourite nhất ở phía trái có
  498.   hạng không nhỏ hơn threshold.
  499.   */
  500. int blocker = segmentTree.findLast(
  501. 1,
  502. favourite - 1,
  503. threshold
  504. );
  505.  
  506. int oppositeSeatsBefore;
  507.  
  508. if (blocker == -1) {
  509. oppositeSeatsBefore = favourite - 1;
  510. } else {
  511. oppositeSeatsBefore =
  512. favourite - blocker - 1;
  513. }
  514.  
  515. cout << position - favourite + 1
  516. + oppositeSeatsBefore
  517. << '\n';
  518. } else {
  519. int threshold = segmentTree.rangeMaximum(
  520. position,
  521. favourite - 1
  522. );
  523.  
  524. int blocker = segmentTree.findFirst(
  525. favourite + 1,
  526. n,
  527. threshold
  528. );
  529.  
  530. int oppositeSeatsBefore;
  531.  
  532. if (blocker == -1) {
  533. oppositeSeatsBefore = n - favourite;
  534. } else {
  535. oppositeSeatsBefore =
  536. blocker - favourite - 1;
  537. }
  538.  
  539. cout << favourite - position + 1
  540. + oppositeSeatsBefore
  541. << '\n';
  542. }
  543. }
  544. }
  545.  
  546. return 0;
  547. }
  548.  
Success #stdin #stdout 0.01s 5296KB
stdin
Standard input is empty
stdout
Standard output is empty