制約がたくさんあって面倒です。
どこに時間がかかりそうか考えたところ、$T_{i} = 2$ のときの右シフトを配列で愚直にやってしまうと時間がかかってしまいそうです。
右シフトですが、配列の開始位置の添字を$-1$ずらすだけでいけることがわかります。
添字が$0$より小さくなってしまう場合が出てきてしまうので、$N$の剰余を求めて配列開始位置の添字とします。
配列の開始位置の添字をstart
とすると、i
番目の要素にアクセスするためには、A[(i + start - 1) % N]
で出来ます。
その計算をソースコードに落とし込んだのが以下です。
言語はC++(GCC 9.2.1)でAtCoderのコードテストで確認しています。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int main() {
ll N, Q;
cin >> N >> Q;
vector<int> A(N), T(Q), X(Q), Y(Q);
for (int i = 0; i <N; i++) {
cin >> A[i];
}
for (int i = 0; i < Q; i++) {
cin >> T[i] >> X[i] >> Y[i];
X[i]--;
Y[i]--;
}
int start = 0;
for (int i = 0; i < Q; i++) {
if (T[i] == 1) {
swap(A[(X[i] + start) % N], A[(Y[i] + start) % N]);
} else if (T[i] == 2) {
start = (start - 1 + N) % N;
} else if (T[i] == 3) {
cout << A[(X[i] + start) % N] << endl;
}
}
}