Problem:
Problem I : RMQ

n 個の数字a0 ,a1 , ... ,an-1 とq が与えられる。

q 個のクエリーに対して適切な処理を行なって欲しい。

クエリーは以下の3種類の操作が存在する。

値のシフトを行う

l とr のペアが与えられる。(l < r )
al から ar までの値を Circular Shiftさせる。

0 1 2 3 4 5 6 7 8 9

に対してl=2,r=5というクエリーが与えられたとする。

シフトを行った数字列は

0 1 5 2 3 4 6 7 8 9

となる。

最小値を求める

l とr のペアが与えられる。(l ≤ r )

al から arまでの値の中で最小の値を求める。

値の更新

pos と val のペアが与えられる。
apos の値を val に更新する。

Input

入力は以下のフォーマットで与えられる。

n q
a0
a1
.
.
.
an-1
x1 y1 z1
x2 y2 z2
.
.
.
xq yq zq

xi = 0 なら、シフトのクエリーを表す。このとき、l = yi , r = zi とする。

xi = 1 なら、最小値を求めるクエリーを表す。このとき、l = yi , r = zi とする。

xi = 2 なら、値を更新するクエリーを表す。このとき、pos = yi , val = zi とする。

入力は以下の制約を満たす

1 ≤ n , q ≤ 200,000

0 ≤ ai ≤ 10,000,000

値を更新するクエリーについて、0 ≤ val ≤ 10,000,000

Output

クエリーとしてxi = 1 が与えられたときに、答えの値を１行に出力せよ。

Sample Input 1

10 3
0
1
2
3
4
5
6
7
8
9
1 5 7
0 2 5
1 5 7

Sample Output 1

5
4

Sample Input 2

10 10
289383
930886
692777
636915
747793
238335
885386
760492
516649
641421
2 7 368690
1 3 6
0 2 6
1 1 8
0 2 9
2 2 665123
1 5 9
0 2 8
2 7 961393
1 1 2

Sample Output 2

238335
238335
238335
368690

Solution in C++11 (judge verdict: Time Limit Exceeded)

#include <algorithm>
#include <iostream>
#include <vector>

using namespace std;

#define INF 100000000000000

template <typename T>
struct segment {
  segment(std::size_t m) : m(m) {
    n = 1;
    while (n < m) n *= 2;
    data.resize(2 * n);
    for (std::size_t i = 0; i < 2 * n - 1; ++i) {
      data[i] = static_cast<T>(INF);
    }
  }

  void update(std::size_t idx, const T& value) {
    idx += n - 1;  // leaf
    data[idx] = value;
    while (idx > 0) {
      idx = (idx - 1) / 2;  // parent

      // RMQ
      data[idx] = std::min(data[idx * 2 + 1], data[idx * 2 + 2]);
    }
  }

  // [first, last)
  T query(std::size_t first, std::size_t last) {
    return query(first, last, 0, 0, n);
  }

  T query(std::size_t first, std::size_t last,
          std::size_t node, std::size_t l, std::size_t r) {
    if (r <= first || last <= l) return static_cast<T>(INF);
    if (first <= l && r <= last) return data[node];
    std::size_t m = (l + r) / 2;

    // RMQ
    return std::min(query(first, last, 2 * node + 1, l, m),
                    query(first, last, 2 * node + 2, m, r));
  }

  std::size_t size() const {
    return m;
  }

  T get(std::size_t idx) {
    idx += n - 1;
    return data[idx];
  }

  std::vector<T> data;
  std::size_t m;
  std::size_t n;
};

int N, Q;

int main() {
  cin >> N >> Q;
  segment<unsigned long long> segtree(N);
  
  for (int i = 0; i < N; ++i) {
    int tmp;
    cin >> tmp;
    segtree.update(i, tmp);
  }

  for (int i = 0; i < Q; ++i) {
    int x, y, z;
    cin >> x >> y >> z;

    if (x == 0) {
      int last = segtree.get(z);
      for (int j = z; j > y; --j) {
        segtree.update(j, segtree.get(j - 1));
      }
      segtree.update(y, last);
    } else if (x == 1) {
      cout << segtree.query(y, z + 1) << endl;
    } else {
      segtree.update(y, z);
    }
  }
}