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 C (Clang 10.0.0) (judge verdict: Time Limit Exceeded)

#include <stdio.h>

int main()
{

    long long int n;
    long long int x;
    int m;
    int mark[100001];
    for (int k = 0; k <= 100000;k++){
        mark[k] = 0;
    }
    int remember[300000];
    unsigned long long int remembersum[300000];
    long long int remembercount[300000];
    int r=0;
    int flag =0;//繰り返し

    scanf("%lld", &n);
    scanf("%lld", &x);
    scanf("%d", &m);

    unsigned long long int sum = 0;
    int i;
    int j;
    sum = x;
    for (i = 1; i < n;i++){
        if(x*x-m>0){
            x = (x * x )% m;
            if(mark[x]==1){

                for (j = 0; j < r;j++){
                    if(remember[j]==x){
                        flag = 1;
                        //printf("*find*%lld\n", x);
                        sum += x;
                        break;
                        
                        //同じの発見
                    }
                }
                //同じの発見したら抜ける
                if(flag==1)
                    break;
            }
        }
        else if (x * x - m == 0)
        {
            break;
        }
        else
            x = x * x;

        sum += x;
        //if(x<100000){
        mark[x] = 1;
        remember[r] = x;
        remembersum[r] = sum;
        remembercount[r] = i;
        r++;
        if (r >= 100000)
            r = 0;
        //printf("*remember*%lld\n", x);
        //}
        
    }
    if(flag==1){
        unsigned long long partsum = sum - remembersum[j];
        long long int partcount = i - remembercount[j];
        sum += (((long long int)(n - 1 - i) / partcount)) * partsum;
        n = (n -1- i) % partcount;
        x = remember[j];
        for (i = 0; i < n; i++)
        {
            if (x * x - m >= 0)
            {
                x = (x * x) % m;
               
            }
            else
                x = x * x;

            sum += x;
          
        }
    }

    printf("%lld", sum);

    printf("\n");
}