Problem:
MathJax.Hub.Config({ tex2jax: { inlineMath: [["$","$"], ["\\(","\\)"]], processEscapes: true }});

環状すごろく

ユキさんは、子供会の催しでみんなで遊べるようにすごろくを作りました。このすごろくでは、環状にマスが並んでいて、それぞれのマスには１以上の整数が書いてあります。

プレイヤーは出発点としてどこかのマスを選んで自分の駒を置きます。そのマスに書いてある数だけ、時計回りに駒を進めます。止まったマスに書いてある数だけ、再び時計回りに駒を進めます。これを繰り返して、出発点に選んだマスの上で駒が止まったら「あがり」です。

実際には、マスの選び方によっては絶対に「あがり」にならない場合もあります。ユキさんは、このすごろくで「あがり」にたどり着けるマスの個数を数えようとしています。

すごろくの情報を入力とし、「あがり」にたどり着けるマスの個数を報告するプログラムを作成せよ。

Input

入力は以下の形式で与えられる。

N
a1 a2 ... aN

１行目にすごろくに含まれるすべてのマスの個数 N (1 ≤ N ≤ 100000) が与えられる。２行目に、それぞれのマスに書かれた数 ai (1 ≤ ai ≤ 109) が、時計回りに順番に与えられる。

Output

「あがり」にたどり着けるマスの個数を１行に出力する。

Sample Input 1

3
1 1 1

Sample Output 1

3

Sample Input 2

3
1 1 2

Sample Output 2

2

Sample Input 3

8
2 3 7 3 3 3 4 4

Sample Output 3

6

Solution in C++ (judge verdict: Accepted)

#include<bits/stdc++.h>
using namespace std;

int main(){
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  int n;
  cin >> n;

  int data[100010];
  for(int i = 0;i < n;i++){
    cin >> data[i];
  }

  bool ans[100010] = {};
  bool finish[100010] = {};
  for(int p = 0;p < n;p++){
    if(finish[p]) continue;
    bool used[100010] = {};
    int now = p;
    stack<int> dfs;
    while(!used[now] && !finish[now]){
      dfs.push(now);
      used[now] = true;
      now = (now + data[now]) % n;
    }
    bool ok = true;
    if(finish[now]){
      ok = false;
    }
    while(!dfs.empty()){
      int tmp = dfs.top();
      dfs.pop();
      ans[tmp] = ok;
      finish[tmp] = true;
      if(tmp == now) ok = false;
    }
  }
  int anss = 0;
  for(int i = 0;i < n;i++){
    if(ans[i]) anss++;
  }
  cout << anss << endl;
  return 0;
}