Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- int mul(int a, int b, int m) {
- if (a == 0 || b == 0) {
- return 0;
- }
- if (b == 1)
- return a;
- if (b % 2 == 0) {
- int t = mul(a, b / 2, m);
- return (2 * t) % m;
- }
- return (mul(a, b - 1, m) + a) % m;
- }
- long long **dot(long long ** const A, long long ** const B, int n, int PP) {
- long long **res = malloc(sizeof(long long*) * n);
- for (int i = 0; i < n; ++i) {
- res[i] = malloc(sizeof(long long) * n);
- }
- for (int i = 0; i < n; ++i) {
- for (int j = 0; j < n; ++j) {
- long long sum = 0;
- for (int k = 0; k < n; ++k) {
- sum += A[i][k] * B[k][j];
- sum %= PP;
- }
- res[i][j] = sum % PP;
- }
- }
- return res;
- }
- long long **binpow (long long **arr, int n, int k, long long **I, int PP) {
- long long **arr1 = malloc(k * sizeof(long long*));
- for (int i = 0; i < k; ++i) {
- arr1[i] = malloc(sizeof(long long) * k);
- memcpy(arr1[i], arr[i], k * sizeof(long long));
- }
- if (n == 1) {
- return arr;
- }
- if (n == 0)
- return I;
- if (n % 2 == 1)
- return dot(binpow(arr1, n-1, k, I, PP), arr1, k, PP);
- else {
- long long **b = binpow(arr1, n/2, k, I, PP);
- return dot(b, b, k, PP);
- }
- }
- void PowArray (int **res, int **arr, int N, int pow, int PP)
- { int i, j, k, p = 1;
- int **temp = malloc(N * sizeof(int*));
- for (int i = 0; i < N; i++)
- {
- temp[i] = malloc(sizeof(int) * N);
- memset(temp[i], 0, N * sizeof(int));
- }
- for (i = 0; i<N; i++)
- for (j = 0; j<N; j++)
- res[i][j] = arr[i][j];
- while (++p <= pow)
- { for (i = 0; i<N; i++)
- for (j = 0; j<N; j++)
- for (k = 0; k<N; k++) {
- temp[i][j] += res[i][k] * arr[k][j];
- // temp[i][j] += mul(res[i][k], arr[k][j], PP);
- temp[i][j] %= PP;
- }
- for (i = 0; i<N; i++)
- for (j = 0; j<N; j++)
- { res[i][j] = temp[i][j];
- temp[i][j] = 0;
- }
- }
- //free memory
- for (int i = 0; i < N; i++)
- {
- free(temp[i]);
- }
- free(temp);
- }
- int main(void)
- {
- int k, n, p;
- scanf("%d %d %d", &k, &n, &p);
- long long *koefs = malloc(k * sizeof(long long));
- long long *firsts = malloc(k * sizeof(long long));
- for (int i = 0; i < k; i++)
- {
- scanf("%lld", &firsts[i]);
- }
- for (int i = 0; i < k; i++)
- {
- scanf("%lld", &koefs[i]);
- }
- long long **arr = malloc(k * sizeof(long long*));
- long long **res = malloc(k * sizeof(long long*));
- long long **I = malloc(k * sizeof(long long*));
- for (int i = 0; i < k; i++)
- {
- arr[i] = malloc(sizeof(long long) * k);
- res[i] = malloc(sizeof(long long) * k);
- I[i] = malloc(sizeof(long long) * k);
- }
- memcpy(arr[0], koefs, k * sizeof(long long));
- memcpy(res[0], koefs, k * sizeof(long long));
- memset(I[0], 0, k * sizeof(long long));
- for (int i = 1; i < k; i++)
- {
- memset(arr[i], 0, k * sizeof(long long));
- memset(res[i], 0, k * sizeof(long long));
- memset(I[i], 0, k * sizeof(long long));
- for (int j = 0; j < k; j++)
- {
- if (j == i - 1) {
- arr[i][j] = 1;
- res[i][j] = 1;
- }
- }
- }
- for (int i = 0; i < k; ++i) {
- I[i][i] = 1;
- }
- if (n == 1) {
- ;
- } else {
- arr = binpow(res, n - 1, k, I, p); // arr, степень, размерность, единичная матрица, модуль
- }
- long long int ans = 0;
- for (int i = 0; i < k; ++i) {
- ans += arr[k - 1][i] * firsts[k - i - 1];
- }
- printf("%lld\n", ans % p);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement