Problem:
旅人

問題

あなたは JOI 街道を旅する旅人である.JOI 街道は東西にまっすぐに延びた道路で,JOI 街道上には n 個の宿場町がある.宿場町には西から東の順に 1 から n までの番号が付けられている.JOI 街道上の最も西の宿場町が宿場町 1 であり,最も東の宿場町が宿場町 n である.

あなたは,宿場町 1 から出発して m 日間の旅に出ることになった.あなたの旅程は数列 a1 , a2 , . . . , am に従い,次のように決められている.ai は i 日目の移動方法を表す 0 ではない整数である.i 日目にあなたが出発する宿場町を宿場町 k とおくと,i 日目にあなたは宿場町 k から宿場町 k + ai までまっすぐに移動することを意味する.

宿場町の個数 n,旅の日数 m,宿場町間の距離の情報と,移動方法を表す数列a1 , a2 , . . . , am が与えられたとき,m 日間の旅におけるあなたの移動距離の合計を100000 = 105 で割った余りを求めるプログラムを作成せよ.

入出力の例に対応する図

入力

1 行目には整数 n, m が空白区切りで書かれている.n (2 ≤ n ≤ 100000 = 105 ) はJOI 街道上の宿場町の個数を,m (1 ≤ m ≤ 100000 = 105 ) は旅の日数を表す.

続く n − 1 行は JOI 街道上の宿場町間の距離を表す.i + 1 行目 (1 ≤ i ≤ n − 1) に
は宿場町 i と宿場町 i + 1 の距離を表す正整数 si (1 ≤ si ≤ 100) が書かれている.

続く m 行には m 日間の移動方法を表す数列が書かれている.i + n 行目 (1 ≤ i ≤ m)
には i 日目のあなたの移動方法を表す 0 ではない整数 ai が書かれている.

採点用データにおいて,宿場町 1 より西に移動することや,宿場町 n より東に移
動することはない.

採点用データのうち,配点の 50% 分については,n ≤ 100 かつ m ≤ 100 を満たす.

出力

出力 は, m 日間の旅におけるあなたの移動距離の合計を 100000 = 105 で割った余りを含む 1 行からなる.

入出力例

入力例 1

7 5
2
1
1
3
2
1
2
-1
3
2
-3

出力例 1

18

1 日目に,あなたは宿場町 1 から宿場町 3 まで移動する.2 日目に,あなたは宿場
町 3 から宿場町 2 まで移動する.そして,3 日目に宿場町 2 から宿場町 5 まで移動
し,4 日目に宿場町 5 から宿場町 7 まで移動し,5 日目に宿場町 7 から宿場町 4 ま
で移動する.5 日間の旅におけるあなたの移動距離の合計は 18 である.

上記問題文と自動審判に使われるデータは、情報オリンピック日本委員会が作成し公開している問題文と採点用テストデータです。

Solution in C (judge verdict: Accepted)

#include <stdio.h>

#define MOD (100000)

int s[100001];

int main(void)
{
    int n, m, a;
    int k;
    int i, j;
    int p;
    int d;
    
    scanf("%d%d", &n, &m);
    
    s[0] = s[1] = 0;
    for (i = 2; i <= n; i++){
        scanf("%d", &k);
        s[i] = s[i - 1] + k;
        s[i] %= MOD;
//printf("[%d=%d]", i, s[i]);
    }
    
    p = 1;
    d = 0;
    for (i = 1; i <= m; i++){
        scanf("%d", &a);
        if (a > 0){
            d += (s[p + a] - s[p] + MOD);
        }
        else {
            d += (s[p] - s[p + a] + MOD);
        }
        
        d %= MOD;
// printf("<%d %d D=%d SUM=%d>", p, a, s[p + a] - s[p], d);
        p += a;
    }
    
    printf("%d\n", d);
    
    return (0);
}