#include #define MAX 100005 #define lli long long #define bkt_size 100 using namespace std; lli A[MAX]; lli sum[MAX]; int steps[MAX]; int nxt[MAX]; int n; struct data { lli val; int steps; int idx; int nxt; data() { } data(lli val, int steps, int idx, int nxt) { this->val = val, this->steps = steps, this->idx = idx, this->nxt = nxt; } }; void update_bucket(int bkt_idx) { if ( bkt_idx < 0 ) return; if ( sum[bkt_idx] ) { for ( int i = bkt_idx*bkt_size; i < min(n, (bkt_idx + 1)*bkt_size); i++ ) { A[i] += sum[bkt_idx]; } sum[bkt_idx] = 0; } if ( sum[bkt_idx + 1] ) { for ( int i = (bkt_idx + 1)*bkt_size; i < min(n, (bkt_idx + 2)*bkt_size); i++ ) { A[i] += sum[bkt_idx + 1]; } sum[bkt_idx + 1] = 0; } stack s; for ( int i = min(n, (bkt_idx + 2)*bkt_size) - 1; i >= (bkt_idx + 1)*bkt_size; i-- ) { while ( !s.empty() && A[i] >= s.top().val ) s.pop(); s.push(data(A[i], 0, i, i)); } for ( int i = min(n, (bkt_idx + 1)*bkt_size) - 1; i >= bkt_idx*bkt_size; i-- ) { while ( !s.empty() && A[i] >= s.top().val ) s.pop(); if ( s.empty() || (s.top().idx - i ) > bkt_size ) { // s.push(data(A[i], 0, i, i)); steps[i] = 0; nxt[i] = -1; } else { steps[i] = s.top().steps + 1; nxt[i] = s.top().nxt; s.push(data(A[i], steps[i], i, nxt[i])); } } } void update(int l, int r, lli x) { if ( l/bkt_size == r/bkt_size ) { for ( int i = l; i <= r; i++ ) A[i] += x; update_bucket(l/bkt_size); update_bucket(l/bkt_size - 1); return; } for ( int i = l; i < (l/bkt_size + 1)*bkt_size; i++ ) { A[i] += x; } for ( int i = (r/bkt_size)*bkt_size; i <= r; i++ ) { A[i] += x; } for ( int i = l/bkt_size + 1; i <= r/bkt_size - 1; i++ ) { sum[i] += x; } update_bucket(r/bkt_size); update_bucket(r/bkt_size - 1); if ( r/bkt_size - 1 != l/bkt_size ) update_bucket(l/bkt_size); update_bucket(l/bkt_size - 1); } int query(int idx, int k) { while ( 1 ) { if ( steps[idx] > k || steps[idx] == 0 ) break; k -= steps[idx]; idx = nxt[idx]; } if ( k == 0 ) return idx; int cur_bkt = idx/bkt_size; for ( int i = idx + 1; i < min(n, (cur_bkt + 1)*bkt_size); i++ ) { if ( k == 0 ) break; if ( A[i] > A[idx] ) { k--; idx = i; } } return idx; } int main() { int q, type, idx, k, l, r; lli x; cin >> n >> q; assert(n >= 1 && n <= 100000); assert(q >= 1 && q <= 100000); for ( int i = 0; i < n; i++ ) { cin >> A[i]; assert(A[i] >= 1 && A[i] <= 1000000); } for ( int i = (n - 1)/bkt_size; i >= 0; i-- ) { update_bucket(i); } while ( q-- ) { cin >> type; assert(type == 1 || type == 2); if ( type == 1 ) { cin >> idx >> k; assert(idx >= 1 && idx <= n); assert(k >= 1 && k <= n); idx--; cout << query(idx, k) + 1 << endl; } else { cin >> l >> r >> x; assert(l >= 1 && l <= n); assert(r >= 1 && r <= n); assert(x >= -1000000 && x <= 1000000); l--, r--; update(l, r, x); } } return 0; }