Problem:
Score : 500 points

Problem Statement

Let us denote by f(x, m) the remainder of the Euclidean division of x by m.

Let A be the sequence that is defined by the initial value A_1=X and the recurrence relation A_{n+1} = f(A_n^2, M).
Find \displaystyle{\sum_{i=1}^N A_i}.

Constraints

1 \leq N \leq 10^{10}

0 \leq X < M \leq 10^5

All values in input are integers.

Input

Input is given from Standard Input in the following format:

N X M

Output

Print \displaystyle{\sum_{i=1}^N A_i}.

Sample Input 1

6 2 1001

Sample Output 1

1369

The sequence A begins 2,4,16,256,471,620,\ldots Therefore, the answer is 2+4+16+256+471+620=1369.

Sample Input 2

1000 2 16

Sample Output 2

6

The sequence A begins 2,4,0,0,\ldots Therefore, the answer is 6.

Sample Input 3

10000000000 10 99959

Sample Output 3

492443256176507

Solution in Rust (1.42.0) (judge verdict: Accepted)

use proconio::{fastout, input};
use std::io::*;
use std::str::FromStr;

use std::cmp::{max, min};
use std::collections::{BinaryHeap, HashMap, HashSet, VecDeque};

fn main() {
    input! {
        n: usize,
        x: usize,
        m: usize,
    }

    let mut t = 0;
    let mut s = 0;
    let mut sr = vec![0];
    let mut hp = HashMap::new();
    for i in 0..n {
        if i == 0 {
            t = x;
        } else {
            t = t * t % m;
        }

        // the left part is all zero
        if t == 0 {
            break;
        }
        // the left part is some looping
        if hp.contains_key(&t) {
            let pi = *hp.get(&t).unwrap();
            let sl = sr[i] - sr[pi as usize];
            // println!("i:{}, pi:{}, sl:{}", i, pi, sl);
            let d = i - pi;
            let cnt = (n - i) / d;
            s += cnt * sl;
            let r = (n - i) % d;
            // println!("r:{}", r);
            let rv = sr[pi + r] - sr[pi];
            s += rv;
            // println!("cnt:{}, sum:{}", cnt, s);
            break;
        }

        hp.insert(t, i);
        s += t;
        sr.push(s);
    }

    // let mut a = vec![0; n];
    // let mut v = vec![0];
    // let mut sum = x;
    // let mut map: HashMap<usize, usize> = HashMap::new();
    // a[0] = x;
    // for i in 1..n {
    //     let x = a[i - 1].pow(2) % m;
    //     if x == 0 {
    //         break;
    //     }
    //     if map.contains_key(&x) {
    //         let l = map.get(&x).unwrap();
    //         let r = i - 1;
    //         println!("l:{}, r:{}, v:{}", l, r, v.len());
    //         sum += (v[r] - v[*l - 1 as usize]) * n - l / (r - *l + 1);
    //         break;
    //     }
    //     map.insert(x, i);
    //
    //     sum += x;
    //     a[i] = x;
    //     v.push(sum);
    // }
    println!("{}", s);
}