Codeforces1106F BSGS矩阵快速幂exgcd
Posted dream-maker-yk
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces1106F BSGS矩阵快速幂exgcd相关的知识,希望对你有一定的参考价值。
首先矩阵快速幂可以算出来第k项的指数,然后可以利用原根的性质,用bsgs和exgcd把答案解出来
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll N = 1e2 + 10;
const ll Mod = 998244353;
ll add(ll a, ll b, ll mod = Mod) {
return (a += b) >= mod ? a - mod : a;
}
ll sub(ll a, ll b, ll mod = Mod) {
return (a -= b) < 0 ? a + mod : a;
}
ll mul(ll a, ll b, ll mod = Mod) {
return 1ll * a * b % mod;
}
ll fast_pow(ll a, ll b, ll mod = Mod) {
ll res = 1;
for (; b; b >>= 1, a = mul(a, a, mod))
if (b & 1) res = mul(res, a, mod);
return res;
}
ll n, m, k, b[N];
struct Matrix {
ll g[N][N];
Matrix() {
memset(g, 0, sizeof(g));
}
};
Matrix operator * (const Matrix a, const Matrix b) {
Matrix c;
for (ll i = 1; i <= k; i++)
for (ll j = 1; j <= k; j++)
for (ll p = 1; p <= k; p++)
c.g[i][j] = add(c.g[i][j], mul(a.g[i][p], b.g[p][j], Mod - 1), Mod - 1);
return c;
}
Matrix fast_pow(Matrix a, ll b) {
Matrix res;
for (ll i = 1; i <= k; i++)
res.g[i][i] = 1;
for (; b; b >>= 1, a = a * a)
if (b & 1) res = res * a;
return res;
}
ll bsgs(ll a, ll b) {
map<ll, ll> mp;
mp[b] = 0;
ll cur = 1, limit = sqrt(Mod);
for (ll i = 1; i <= limit; i++) {
cur = mul(cur, a);
mp[mul(b, fast_pow(cur, Mod - 2))] = i;
}
ll now = 1;
for (ll i = 0; i <= limit; i++) {
if (mp.count(now))
return limit * i + mp[now];
now = mul(now, cur);
}
return -1;
}
ll gcd(ll a, ll b) {
return b ? gcd(b, a % b) : a;
}
void exgcd(ll a, ll b, ll &x, ll &y) {
if (!b) {
x = 1, y = 0;
return;
}
exgcd(b, a % b, y, x);
y -= a / b * x;
}
ll exgcd(ll a, ll b, ll c) {
ll g = gcd(a, b);
if (c % g) return -1;
ll x, y;
exgcd(a, b, x, y);
x *= c / g;
x = (x % (b / g) + (b / g)) % (b / g);
return x;
}
int main() {
#ifdef dream_maker
freopen("input.txt", "r", stdin);
#endif
scanf("%lld", &k);
for (ll i = 1; i <= k; i++)
scanf("%lld", &b[i]);
scanf("%lld %lld", &n, &m);
Matrix tmp;
for (ll i = 1; i < k; i++)
tmp.g[i][i + 1] = 1;
for (ll i = 1; i <= k; i++)
tmp.g[k][i] = b[k - i + 1];
tmp = fast_pow(tmp, n - k);
ll ans1 = bsgs(3, m), ans2 = exgcd(tmp.g[k][k], Mod - 1, ans1);
if (ans1 == -1 || ans2 == -1)
printf("-1");
else
printf("%lld", fast_pow(3, ans2));
return 0;
}
以上是关于Codeforces1106F BSGS矩阵快速幂exgcd的主要内容,如果未能解决你的问题,请参考以下文章
CF1106F Lunar New Year and a Recursive Sequence——矩阵快速幂&&bsgs
CF1106F Lunar New Year and a Recursive Sequence 原根矩阵快速幂高次剩余BSGS
Codeforces 1106F Lunar New Year and a Recursive Sequence (数学线性代数线性递推数论BSGS扩展欧几里得算法)
F. Lunar New Year and a Recursive Sequence(矩阵快速幂+BSGS)
Codeforces Round #257 (Div. 2) B. Jzzhu and Sequences (矩阵快速幂)