Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- void multiply(int k, unsigned long long **a, unsigned long long **b, unsigned long long p) {
- unsigned long long **C = malloc(k * sizeof(unsigned long long *));
- for (int i = 0; i < k; i++)
- C[i] = calloc(k, sizeof(unsigned long long));
- for (int i = 0; i < k; i++)
- for (int j = 0; j < k; j++)
- for (int s = 0; s < k; s++) {
- C[i][j] += a[i][s] * b[s][j];
- C[i][j] %= p;
- }
- for (int i = 0; i < k; i++)
- for (int j = 0; j < k; j++)
- a[i][j] = C[i][j];
- free(C);
- }
- void binpow(unsigned long long **a, unsigned long long **res, unsigned long long n, int k, unsigned long long p) {
- while (n) {
- if (n & 1)
- multiply(k, res, a, p);
- multiply(k, a, a, p);
- n >>= 1;
- }
- }
- int main(void) {
- int k;
- unsigned long long n, p;
- scanf("%d %llu %llu", &k, &n, &p);
- unsigned long long **A = malloc(k * sizeof(unsigned long long *));
- for (int i = 0; i < k; i++)
- A[i] = calloc(k, sizeof(unsigned long long));
- unsigned long long **B = malloc(k * sizeof(unsigned long long *));
- for (int i = 0; i < k; i++) {
- B[i] = calloc(k, sizeof(unsigned long long));
- B[i][i] = 1;
- }
- unsigned long long F[k];
- unsigned long long Fn = 0;
- unsigned long long pow = n - k;
- for (int i = k - 1; i >= 0; i--)
- scanf("%llu", &F[i]);
- if (n <= k) {
- printf("%llu", F[k - n] % p);
- return 0;
- }
- for (int i = 0; i < k; i++)
- scanf("%llu", &A[0][i]);
- for (int i = 0; i < k - 1; i++)
- A[i + 1][i] = 1;
- binpow(A, B, pow, k, p);
- for (int i = 0; i < k; i++) {
- Fn += B[0][i] * F[i];
- Fn %= p;
- }
- printf("%llu", Fn);
- free(A);
- free(B);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement