哎呀大水题。。我写了一个多小时。。好没救啊。。

数论板子X合一?

注意: 本文中变量名称区分大小写。

题意: 给一个\(n\)阶递推序列\(f_k=\prod^{n}_{i=1} f_{k-i}^{b_i}\mod P\)其中\(P=998244353\), 输入\(b_1,b_2,...,b_n\)以及已知\(f_1,f_2,...,f_{n-1}=1\), 再给定一个数\(m\)和第\(m\)项的值\(f_m\), 求出一个合法的\(f_n\)值使得按照这个值递推出来的序列满足第\(m\)项的值为给定的\(f_m\).

题解: 首先一个显然的结论是\(f_m\)可以表示成\(\prod^{n}_{i=1} f_i^{a_i}\), 而且由于\(i=1,2,...,n-1\)时\(f_i\)的任何次幂都为\(1\), 因此就是\(f_m=f_n^{a}\). 令\(A(m)\)为\(f_m\)内\(f_n\)的次数,则有\(A[1..n]=[0,0,0,0,...,0,1]\), \(A_m=\sum^{n-1}_{i=1} A(m-i)b_i (m>n)\), 即\(A\)数组满足一个常系数线性递推序列。因此可以用矩阵乘法在\(O(n^3\log m)\)的时间内求出\(A(m)\). 注意因为是指数的运算(\((a^n)^m=a^{nm}\)), 根据费马小定理,这个指数应该模\(\phi(P)=P-1\)而不是\(P\) (\((a^n)^m\mod P=a^{nm\mod (P-1)}\mod P\))

求出来\(a=A(m)\)之后这题就变成了,\(f_m=f_n^a\mod P\), 已知\(f_m, a\), 求出一组合法的\(f_n\).

根据常识,\(998244353\)有原根\(3\), 我们下文令\(G=3\) (实际上任何一个原根均可). 设\(f_m=G^p, f_n=G^q\), 则有\(G^p\equiv (G^q)^a (\mod P)\), \(p\equiv qa(\mod P-1)\), 然后用BSGS求离散对数\(p\), exgcd解出\(q\)就可以了啊……

时间复杂度\(O(\sqrt P\log P+n^3\log P)\)

坑: 注意解同余方程的时候那个\(P\)的系数不要设成负的。

代码

  1. #include<cstdio>
  2. #include<cstdlib>
  3. #include<cstring>
  4. #include<map>
  5. #define llong long long
  6. using namespace std;
  7. const int N = 100;
  8. const int G = 3;
  9. const int P = 998244353;
  10. llong quickpow(llong x,llong y)
  11. {
  12. llong cur = x,ret = 1ll;
  13. for(int i=0; y; i++)
  14. {
  15. if(y&(1ll<<i)) {y-=(1ll<<i); ret = ret*cur%P;}
  16. cur = cur*cur%P;
  17. }
  18. return ret;
  19. }
  20. struct Matrix
  21. {
  22. llong a[N+3][N+3]; int sz1,sz2,sz;
  23. void init() {for(int i=1; i<=sz1; i++) for(int j=1; j<=sz2; j++) a[i][j] = 0ll;}
  24. Matrix() {}
  25. Matrix(int _sz) {sz = sz1 = sz2 = _sz; init();}
  26. Matrix(int _sz1,int _sz2) {sz1 = _sz1,sz2 = _sz2; init();}
  27. void uinit(int _sz) {sz = sz1 = sz2 = _sz; for(int i=1; i<=sz; i++) for(int j=1; j<=sz; j++) a[i][j] = (i==j)?1:0;}
  28. void output() {for(int i=1; i<=sz1; i++) {for(int j=1; j<=sz2; j++) printf("%lld ",a[i][j]); puts("");}}
  29. };
  30. Matrix operator *(Matrix x,Matrix y)
  31. {
  32. Matrix ret = Matrix(x.sz1,y.sz2);
  33. for(int i=1; i<=x.sz1; i++)
  34. {
  35. for(int j=1; j<=x.sz2; j++)
  36. {
  37. for(int k=1; k<=y.sz2; k++)
  38. {
  39. ret.a[i][j] = (ret.a[i][j]+x.a[i][k]*y.a[k][j])%(P-1ll);
  40. }
  41. }
  42. }
  43. return ret;
  44. }
  45. Matrix mquickpow(Matrix x,llong y)
  46. {
  47. Matrix cur = x,ret; ret.uinit(x.sz);
  48. for(int i=0; y; i++)
  49. {
  50. if(y&(1ll<<i)) {y-=(1ll<<i); ret = ret*cur;}
  51. cur = cur*cur;
  52. }
  53. return ret;
  54. }
  55. namespace BSGS
  56. {
  57. const int B = 31595;
  58. map<llong,int> mp;
  59. void init()
  60. {
  61. llong bs = quickpow(G,B); llong j = 1ll;
  62. for(int i=0; i<=P; i+=B,j=(j*bs)%P)
  63. {
  64. mp[j] = i;
  65. }
  66. }
  67. llong Logarithm(llong x)
  68. {
  69. llong j = 1ll;
  70. for(int i=0; i<=B; i++,j=(j*G)%P)
  71. {
  72. llong tmp = x*j%P;
  73. if(mp.count(tmp))
  74. {
  75. llong ret = (mp[tmp]-i+(P-1))%(P-1);
  76. return ret;
  77. }
  78. }
  79. return P-1;
  80. }
  81. }
  82. Matrix mA,mB,mC;
  83. llong a[N+3],b[N+3];
  84. int n; llong m,p,q,lq,lx;
  85. llong gcd(llong x,llong y) {return y==0 ? x : gcd(y,x%y);}
  86. void exgcd(llong _a,llong _b,llong &_x,llong &_y)
  87. {
  88. if(_b==0ll) {_x = 1ll,_y = 0ll; return;}
  89. exgcd(_b,_a%_b,_x,_y);
  90. llong tmp = _x; _x = _y; _y = tmp-(_a/_b)*_y;
  91. }
  92. llong CongruenceEquation(llong _a,llong _b,llong mod)
  93. {
  94. llong g = gcd(_a,mod),x,y;
  95. exgcd(_a/g,mod/g,x,y);
  96. return (x*(_b/g)%mod+mod)%mod;
  97. }
  98. int main()
  99. {
  100. BSGS::init();
  101. scanf("%d",&n);
  102. for(int i=1; i<=n; i++) scanf("%I64d",&b[i]);
  103. scanf("%I64d",&m);
  104. mA = Matrix(1,n); mA.a[1][1] = 1ll;
  105. mB = Matrix(n); for(int i=1; i<n; i++) mB.a[i][i+1] = 1ll; for(int i=1; i<=n; i++) mB.a[i][1] = b[i];
  106. mC = mA*mquickpow(mB,m-n); p = mC.a[1][1]; scanf("%I64d",&q);
  107. lq = BSGS::Logarithm(q);
  108. if(lq%gcd(P-1,p)!=0) {printf("-1\n"); return 0;}
  109. lx = CongruenceEquation(p,lq,P-1);
  110. llong ans = quickpow(G,lx);
  111. printf("%I64d\n",ans);
  112. return 0;
  113. }

Codeforces 1106F Lunar New Year and a Recursive Sequence (数学、线性代数、线性递推、数论、BSGS、扩展欧几里得算法)的更多相关文章

  1. Codeforces 1106F Lunar New Year and a Recursive Sequence | BSGS/exgcd/矩阵乘法

    我诈尸啦! 高三退役选手好不容易抛弃天利和金考卷打场CF,结果打得和shi一样--还因为queue太长而unrated了!一个学期不敲代码实在是忘干净了-- 没分该没分,考题还是要订正的 =v= 欢迎 ...

  2. @codeforces - 1106F@ Lunar New Year and a Recursive Sequence

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 定义递推数列 f: (1)f[1] = f[2] = ... f ...

  3. CF1106F Lunar New Year and a Recursive Sequence 原根、矩阵快速幂、BSGS

    传送门 好久没写数论题了写一次调了1h 首先发现递推式是一个乘方的形式,线性递推和矩阵快速幂似乎都做不了,那么是否能够把乘方运算变成加法运算和乘法运算呢? 使用原根!学过\(NTT\)的都知道\(99 ...

  4. CF1106F Lunar New Year and a Recursive Sequence

    题目链接:CF1106F Lunar New Year and a Recursive Sequence 大意:已知\(f_1,f_2,\cdots,f_{k-1}\)和\(b_1,b_2,\cdot ...

  5. CF1106F Lunar New Year and a Recursive Sequence 线性递推 + k次剩余

    已知\(f_i = \prod \limits_{j = 1}^k f_{i - j}^{b_j}\;mod\;998244353\),并且\(f_1, f_2, ..., f_{k - 1} = 1 ...

  6. CF1106F Lunar New Year and a Recursive Sequence(矩阵快速幂+bsgs+exgcd)

    题面 传送门 前置芝士 \(BSGS\) 什么?你不会\(BSGS\)?百度啊 原根 对于素数\(p\)和自然数\(a\),如果满足\(a^x\equiv 1\pmod{p}\)的最小的\(x\)为\ ...

  7. CF1106F Lunar New Year and a Recursive Sequence——矩阵快速幂&&bsgs

    题意 设 $$f_i = \left\{\begin{matrix}1 , \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \  i < k\\ ...

  8. Educational Codeforces Round 63 (Rated for Div. 2) D. Beautiful Array(动态规划.递推)

    传送门 题意: 给你一个包含 n 个元素的序列 a[]: 定义序列 a[] 的 beauty 为序列 a[] 的连续区间的加和最大值,如果全为负数,则 beauty = 0: 例如: a[] = {1 ...

  9. Codeforces Gym10081 A.Arcade Game-康托展开、全排列、组合数变成递推的思想

    最近做到好多概率,组合数,全排列的题目,本咸鱼不会啊,我概率论都挂科了... 这个题学到了一个康托展开,有点用,瞎写一下... 康托展开: 适用对象:没有重复元素的全排列. 把一个整数X展开成如下形式 ...

随机推荐

  1. libcurl实现解析(3) - libcurl对select的使用

    1.前言 在本系列的前一篇文章中.介绍了libcurl对poll()的使用. 參考"libcurl原理解析(2) - libcurl对poll的使用". 本篇文章主要分析curl_ ...

  2. Codeforces Round #250 Div. 2(C.The Child and Toy)

    题目例如以下: C. The Child and Toy time limit per test 1 second memory limit per test 256 megabytes input ...

  3. Oracle数据库版本号定期检视与升级的必要性分析

    目 录 ▇1.ORACLE数据库版本号知识 ▇2.看看自己的数据库还有没有支持服务 ▇3.看11.2.0.3版本号各PSU的公布时间与解决BUG数量列表 ▇4.看11.2.0.4版本号各PSU的公布时 ...

  4. Linux framebuffer显示bmp图片【转】

    本文转载自:http://blog.csdn.net/luxiaoxun/article/details/7622988 framebuffer简介 帧缓冲(framebuffer)是Linux为显示 ...

  5. Moon Http Server,强大如斯的全脚本web服务器

    Moon Http Server(MHS) 是一个使用Pascal脚本的高性能Web服务器. 昨天晚上是第一次接触.花了30分钟入门,非常强大.是Delphi 者开发Web的福音. 引用一下作者的介绍 ...

  6. sublime text 快键键

    sublime text 的快捷键ctrl+l                              选择整行(按住-继续选择下行)ctrl+shift+k                    ...

  7. .Net Core中使用Quartz.Net Vue开即用的UI管理

    Quartz.NET Quartz.Net 定制UI维护了常用作业添加.删除.修改.停止.启动功能,直接使用cron表达式设置作业执行间隔,有完整的日志记录. Quartz.NET是一个功能齐全的开源 ...

  8. CAS配置记录

    CAS配置(1)之证书配置 CAS配置(2)之主配置 CAS配置(3)之restful-api接入接口

  9. JDK介绍

    Java的版本最开始是1995年的JDK Alpha and Beta版本,第二年发布JDK1.0版本之后就是JDK1.1,JDK1.2.到1998年,不再叫JDK了,而是叫J2SE,但是版本号还是继 ...

  10. windows phone控件

    常用控件: 包括: Button控件.CheckBox控件.HyperlinkButton控件.Iamege控件.ListBox控件.PasswordBox控件.ProgressBar控件.Radio ...