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++11 (judge verdict: Accepted)

#include<iostream>
#include<cassert>
#include<climits>
#include<algorithm>
#include<vector>
#include<cstring>
#include<deque>

#define REP(i,s,n) for(int i=s;i<n;++i)
#define rep(i,n) REP(i,0,n)

using namespace std;

#define MAX 100010
int n, a[MAX];
int state[MAX];
bool visited[MAX];

#define FAIL 0
#define SUCC 1


void compute() {
  memset(state,-1,sizeof state);
  rep(i,n) {
    if( state[i] != -1 ) continue;
    memset(visited, false ,sizeof visited);
    deque<int> deq;
    int cur = i;
    deq.push_back(i);
    visited[i] = true;
    while(1) {
      cur = ( cur + a[cur] ) % n;
      deq.push_back(cur);
      if( state[cur] != -1 ) { // fail
	deq.pop_back();
	while( !deq.empty() ) {
	  state[deq.front()] = FAIL;
	  deq.pop_front();
	}
	break;
      }
      if( visited[cur] ) {
	int stop = cur;
	deq.pop_back();
	state[cur] = SUCC;
	while( deq.back() != stop ) {
	  state[deq.back()] = SUCC;
	  deq.pop_back();
	}
	assert( deq.back() == stop );
	deq.pop_back();
	while( !deq.empty() ) {
	  assert( state[deq.back()] == -1 );
	  state[deq.back()] = FAIL;
	  deq.pop_back();
	}
	break;
      } else {
	visited[cur] = true;
      }
    }
  }
  int answer = 0;
  rep(i,n) answer += ( state[i] == SUCC );
  cout << answer << endl;
}

int main() {
  if( 0 ) {
    srand((unsigned int)time(NULL));
    n = 100000;
    cout << n << endl;
    rep(i,n) {
      if( i ) printf(" ");
      //cout << rand() % 1000000000 + 1;
      cout << 1000000000;
    } puts("");
    return 0;
  }
  cin >> n;
  rep(i,n) cin >> a[i];
  compute();
  return 0;
}