• 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;
    }
    
    
  • 相关阅读:
    Android开源demo---芒果TV-VIP电影播放器
    实现sqrt()函数
    std::string内容包含双引号
    解决win10 SVN不显示绿色和红色的状态显示标志
    win 10 解决 caps键无法退出大写的问题
    webrtc 编译问题:running depot tools as root is sad 的解决办法
    Linux下运行脚本显示“: /usr/bin/env: "bash ": 没有那个文件或目录
    解决报错:no acceptable C compiler found in $PATH when installing python
    linux 打开文件管理器
    windows打开U盘提示 文件或目录损坏且无法读取 解决办法
  • 原文地址:https://www.cnblogs.com/dream-maker-yk/p/10360019.html
Copyright © 2020-2023  润新知