Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <vector>
- int next_2_degree(int value) {
- int i = 0;
- while(value >> i) ++i;
- return 1 << i;
- }
- class SegmentTree {
- public:
- SegmentTree(const std::vector<std::pair<int, int> >& arr, int n, int defaultValue);
- void Update(int pos, int val);
- int ClosestBigger(int pos, int x);
- private:
- std::vector<std::pair<int, int> > tree;
- int default_, size_;
- int closestBigger(int index, int tleft, int tright, int left, int right, int x);
- void build(int index, int left, int right);
- void update(int index, int left, int right, int pos);
- };
- SegmentTree::SegmentTree(const std::vector<std::pair<int, int> >& arr, int n, int defaultValue)
- : default_(defaultValue), size_(next_2_degree(n) * 2), tree(next_2_degree(n) * 2, {defaultValue, defaultValue}) {
- std::copy(arr.begin(), arr.end(), tree.begin() + tree.size() / 2 - 1);
- build(0, 0, size_ / 2 - 1);
- }
- void SegmentTree::build(int index, int left, int right) {
- if (left == right) return;
- const int mid = (left + right) / 2;
- build(2 * index + 1, left, mid);
- build(2 * index + 2, mid + 1, right);
- tree[index].first = std::min(tree[2 * index + 1].first, tree[2 * index + 2].first);
- tree[index].second = std::max(tree[2 * index + 1].second, tree[2 * index + 2].second);
- }
- int SegmentTree::ClosestBigger(int pos, int x) {
- return closestBigger(0, 0, size_ / 2 - 1, pos - 1, size_ / 2 - 1, x);
- }
- int SegmentTree::closestBigger(int index, int tleft, int tright, int left, int right, int x) {
- if (tleft > right || tright < left) return -2;
- if (tleft == tright) {
- if (tree[index].second >= x) {
- return tleft;
- }
- return -2;
- }
- const int mid = (tleft + tright) >> 1;
- if (tleft >= left && tright <= right) {
- if (tree[index].second < x) {
- return -2;
- }
- if (tree[index].first >= x) {
- return tleft;
- }
- if (tree[2 * index + 1].second >= x) {
- return closestBigger(2 * index + 1, tleft, mid, left, right, x);
- }
- if (tree[2 * index + 2].second >= x) {
- return closestBigger(2 * index + 2, mid + 1, tright, left, right, x);
- }
- return -2;
- }
- int lans = closestBigger(2 * index + 1, tleft, mid, left, right, x),
- rans = closestBigger(2 * index + 2, mid + 1, tright, left, right, x);
- if (lans != -2) {
- return lans;
- }
- return rans;
- }
- void SegmentTree::Update(int pos, int val) {
- tree[size_ / 2 + pos - 2] = std::make_pair(val, val);
- update(0, 0, size_ / 2 - 1, pos - 1);
- }
- void SegmentTree::update(int index, int left, int right, int pos) {
- if (left == right) return;
- const int mid = (left + right) / 2;
- if (pos <= mid) {
- update(2 * index + 1, left, mid, pos);
- } else {
- update(2 * index + 2, mid + 1, right, pos);
- }
- tree[index].first = std::min(tree[2 * index + 1].first, tree[2 * index + 2].first);
- tree[index].second = std::max(tree[2 * index + 1].second, tree[2 * index + 2].second);
- }
- int main() {
- std::ios_base::sync_with_stdio(false);
- std::cin.tie(nullptr);
- std::cout.tie(nullptr);
- int n, m;
- std::cin >> n >> m;
- std::vector <std::pair<int, int> > arr(n);
- for (int i = 0; i < n; ++i) {
- std::cin >> arr[i].first;
- arr[i].second = arr[i].first;
- }
- SegmentTree tree(arr, n, -2);
- for (int i = 0; i < m; ++i) {
- int req, pos, x;
- std::cin >> req >> pos >> x;
- if (req) {
- std::cout << tree.ClosestBigger(pos, x) + 1 << '\n';
- } else {
- tree.Update(pos, x);
- }
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement