https://codeforces.com/contest/1106/problem/F

题意

数列公式为\(f_i=(f^{b_1}_{i-1}*f^{b_2}_{i-2}*...*f^{b_k}_{i-k})\)mod\(P\),给出\(f_{1}...f_{k-1}\)和\(f_{n}\),求\(f_{k}\),其中\(P\)等于998244353

题解

  • 3是998244353的离散对数,所以\(f^{b_1}_{i-1} \equiv 3^{h_i*b_1}(modP)\),怎么求离散对数
  • 乘法转化为加法:\(h_{k+1}\equiv(h_{k}*b_1+...+h_{1}*b_k)mod(P-1)\),矩阵快速幂求出\(h_n\)(\(c*h_k(未知数)\)),\(mod(P-1)\)是欧拉降幂,因为\(h_n\)可能会很大
  • 得到\(f_n=3^{h_n}\equiv m(modP)\),bsgs求出\(h_n\),有空填exbsgs的坑
  • 于是得到\(c*h_k\equiv h_n(modP-1)\)的一元同余方程,用exgcd解出\(h_k\),exgcd还有好多用途
  • 然后\(f_k\equiv3^{h_k}(modP)\)

代码

  1. //vector矩阵快速幂板子
  2. #include<bits/stdc++.h>
  3. #define MOD 998244353
  4. #define ll long long
  5. #define vec vector<ll>
  6. #define mat vector<vec>
  7. using namespace std;
  8. mat mul(mat &A,mat &B,ll mod){
  9. mat C(A.size(),vec(B[0].size()));
  10. for(int i=0;i<A.size();i++)
  11. for(int j=0;j<A.size();j++)
  12. for(int k=0;k<A.size();k++)
  13. C[i][j]+=A[i][k]*B[k][j]%mod,C[i][j]%=mod;
  14. return C;
  15. }
  16. mat pw(mat &A,ll x,ll mod){
  17. mat C(A.size(),vec(A.size()));
  18. for(int i=0;i<A.size();i++)C[i][i]=1;
  19. while(x){
  20. if(x&1)C=mul(C,A,mod);
  21. A=mul(A,A,mod);
  22. x>>=1;
  23. }
  24. return C;
  25. }
  26. ll pw(ll bs,ll x,ll mod){
  27. ll ans=1;
  28. while(x){
  29. if(x&1)ans=ans*bs%mod;
  30. bs=bs*bs%mod;
  31. x>>=1;
  32. }
  33. return ans;
  34. }
  35. ll bsgs(ll a,ll b,ll c){
  36. ll m=ceil(sqrt(c));
  37. map<ll,ll>mp;
  38. ll bs=b,BS=pw(a,m,c);
  39. for(int i=1;i<=m;i++){mp[bs]=i-1;bs=bs*a%c;}
  40. bs=1;
  41. for(int i=1;i<=m;i++){
  42. if(mp[bs])return (i-1)*m-mp[bs];
  43. bs=bs*BS%c;
  44. }
  45. return -1;
  46. }
  47. ll exgcd(ll a,ll b,ll &x,ll &y){
  48. ll d=a;
  49. if(b==0)x=1,y=0;
  50. else d=exgcd(b,a%b,y,x),y-=x*(a/b);
  51. return d;
  52. }
  53. ll sol(ll a,ll b,ll m){
  54. if(b==0)return 0;
  55. ll g=__gcd(a,m);
  56. if(b%g)return -1;
  57. a/=g;b/=g;m/=g;
  58. ll x,y;
  59. g=exgcd(a,m,x,y);
  60. x=x*b%m;
  61. return (x+m)%m;
  62. }
  63. ll k,n,m,h,ans;
  64. int main(){
  65. cin>>k;
  66. mat A(k,vec(k));
  67. for(int i=0;i<k;i++)cin>>A[i][0];
  68. for(int i=1;i<k;i++)A[i-1][i]=1;
  69. cin>>n>>m;
  70. A=pw(A,n-k,MOD-1);
  71. h=bsgs(3,m,MOD);
  72. ans=sol(A[0][0],h,MOD-1);
  73. if(ans<0)cout<<-1;
  74. else cout<<pw(3,ans,MOD);
  75. }

Codeforces Round #536 (Div. 2) F 矩阵快速幂 + bsgs(新坑) + exgcd(新坑) + 欧拉降幂的更多相关文章

  1. Product Oriented Recurrence(Codeforces Round #566 (Div. 2)E+矩阵快速幂+欧拉降幂)

    传送门 题目 \[ \begin{aligned} &f_n=c^{2*n-6}f_{n-1}f_{n-2}f_{n-3}&\\ \end{aligned} \] 思路 我们通过迭代发 ...

  2. Codeforces Round #307 (Div. 2) D 矩阵快速幂+快速幂

    D. GukiZ and Binary Operations time limit per test 1 second memory limit per test 256 megabytes inpu ...

  3. Codeforces Round #485 (Div. 2) F. AND Graph

    Codeforces Round #485 (Div. 2) F. AND Graph 题目连接: http://codeforces.com/contest/987/problem/F Descri ...

  4. Codeforces Round #486 (Div. 3) F. Rain and Umbrellas

    Codeforces Round #486 (Div. 3) F. Rain and Umbrellas 题目连接: http://codeforces.com/group/T0ITBvoeEx/co ...

  5. Codeforces Round #501 (Div. 3) F. Bracket Substring

    题目链接 Codeforces Round #501 (Div. 3) F. Bracket Substring 题解 官方题解 http://codeforces.com/blog/entry/60 ...

  6. Codeforces Round 536 (Div. 2) (E)

    layout: post title: Codeforces Round 536 (Div. 2) author: "luowentaoaa" catalog: true tags ...

  7. Codeforces Round #499 (Div. 1) F. Tree

    Codeforces Round #499 (Div. 1) F. Tree 题目链接 \(\rm CodeForces\):https://codeforces.com/contest/1010/p ...

  8. Codeforces 576D Flights for Regular Customers 矩阵快速幂+DP

    题意: 给一个$n$点$m$边的连通图 每个边有一个权值$d$ 当且仅当当前走过的步数$\ge d$时 才可以走这条边 问从节点$1$到节点$n$的最短路 好神的一道题 直接写做法喽 首先我们对边按$ ...

  9. Codeforces 514E Darth Vader and Tree 矩阵快速幂

    Darth Vader and Tree 感觉是个很裸的矩阵快速幂, 搞个100 × 100 的矩阵, 直接转移就好啦. #include<bits/stdc++.h> #define L ...

随机推荐

  1. ThinkPHP 整合微信支付 扫码支付 模式二 图文教程

    这篇文章主要介绍扫码支付场景二. 目前有两种模式,模式一比模式二稍微复杂点,至于模式一与模式二的具体内容,流程,微信开发文档都有详细介绍,这里就不多说废话,接下来赶紧上教程! [title]下载SDK ...

  2. ReactiveX 学习笔记(28)使用 RxJS + React.js 进行 GUI 编程

    课题 程序界面由3个文本编辑框和1个文本标签组成. 要求文本标签实时显示3个文本编辑框所输入的数字之和. 文本编辑框输入的不是合法数字时,将其值视为0. 3个文本编辑框的初值分别为1,2,3. 创建工 ...

  3. Python txt文件读取写入字典的方法(json、eval)

    link:https://blog.csdn.net/li532331251/article/details/78203438 一.使用json转换方法 1.字典写入txt import json d ...

  4. thinkphp 5 _initialize 使用问题

    如果继承的是common的话.控制器的_initialize要先继承父类的_initialize parent::_initialize();

  5. java课程之团队开发冲刺1.1

    一.今日目标 1.完成课程助手的日期显示以及周数显示功能 2.将功能表改成侧面功能栏 3.将代码重新规范,尽量使得主函数简洁明了

  6. ucos中消息队列的应用(二)

    继续说任务间的通信. 本次的任务是在ISR中发送一个消息给任务,ucos的代码中的是非常之简洁和容易理解啊.创建,释放,等待,非常好理解,不再赘述. 说说我遇到的问题,数据帧接收完之后,向消息队列发送 ...

  7. mysql 2pc理解

  8. Python开发【第九篇】:协程、异步IO

    协程 协程,又称微线程,纤程.英文名Coroutine.一句话说明什么是协程,协程是一种用户态的轻量级线程. 协程拥有自己的寄存器上下文和栈.协程调度切换时,将寄存器上下文和栈保存到其他地方,在切换回 ...

  9. functools 之 partial(偏函数)

    当函数的参数个数太多,需要简化时,使用functools.partial可以创建一个新的函数,这个新函数可以固定住原函数的部分参数,从而在调用时更简单.当然,decorator(装饰器) 也可以实现, ...

  10. JavaSE基础知识(5)—面向对象(对象数组和对象关联)

    一.对象数组 1.说明 数组的定义类型为对象类型 2.动态初始化 1.声明并开辟空间 Person[] pers = new Person[长度];2.赋值 for(int i=0;i<pers ...