Official

C - Rotatable Array Editorial by en_translator


Type-\(1\) and type-\(2\) queries costs \(O(1)\) time each, but naively executing a type-\(3\) query costs \(O(N)\) time even if you perform the \(k\)-time repetition at once, imposing a total time complexity of \(O(NQ)\) at worst.
How can we deal with type-\(3\) queries?

In fact, we can rephrase the problem as follows without changing the answers:

  • Regard that the sequence adopts \(0\)-based indexing. That is, reassign indices as \(A=(A_0,A_1,\dots,A_{N-1})\). For queries involving \(p\), subtract \(1\) from it right after you receive it.
  • Initially, let \({\rm offset} = 0\).
  • Process a type-\(1\) query by setting \(A_{(p+{\rm offset})\%N}\) to \(x\).
  • Process a type-\(2\) query by printing \(A_{(p+{\rm offset})\%N}\).
  • Process a type-\(3\) query by setting \({\rm offset}\) to \(({\rm offset} + k) \% N\).

Here, \(p\%q\) denotes the remainder when \(p\) is divided by \(q\).

In short, we optimize the type-\(3\) operation that originally costs \(O(N)\) time by replacing it an \(O(1)\) operation of just updating the value of \({\rm offset}\)
If you increment \({\rm offset}\), the operation of accessing \(A_0\) is done by referring to \(A_1\), and \(A_1\) to \(A_2\), \(\dots\), and \(A_{N-1}\) to \(A_0\). This is nothing but a replacement originally asked by type \(3\).

By this optimization, every query can be handled in \(O(1)\) time, and the problem can be solved in a total of \(O(N+Q)\) time.

Sample code (C++):

#include<bits/stdc++.h>

using namespace std;

int main(){
  int N,Q;
  cin >> N >> Q;
  vector<int> A(N);
  for(int i=0;i<N;i++){
    A[i]=i+1;
  }
  int offset=0;
  while(Q>0){
    Q--;
    int typ;
    cin >> typ;
    if(typ==1){
      int p,x;
      cin >> p >> x;
      p--;
      A[(p+offset)%N]=x;
    }
    else if(typ==2){
      int p;
      cin >> p;
      p--;
      cout << A[(p+offset)%N] << "\n";
    }
    else{
      int k;
      cin >> k;
      offset+=k;
      offset%=N;
    }
  }
  return 0;
}

posted:
last update: