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

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

数论板子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\)的系数不要设成负的。

代码

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<map>
#define llong long long
using namespace std;const int N = 100;
const int G = 3;
const int P = 998244353;
llong quickpow(llong x,llong y)
{llong cur = x,ret = 1ll;for(int i=0; y; i++){if(y&(1ll<<i)) {y-=(1ll<<i); ret = ret*cur%P;}cur = cur*cur%P;}return ret;
}
struct Matrix
{llong a[N+3][N+3]; int sz1,sz2,sz;void init() {for(int i=1; i<=sz1; i++) for(int j=1; j<=sz2; j++) a[i][j] = 0ll;}Matrix() {}Matrix(int _sz) {sz = sz1 = sz2 = _sz; init();}Matrix(int _sz1,int _sz2) {sz1 = _sz1,sz2 = _sz2; init();}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;}void output() {for(int i=1; i<=sz1; i++) {for(int j=1; j<=sz2; j++) printf("%lld ",a[i][j]); puts("");}}
};
Matrix operator *(Matrix x,Matrix y)
{Matrix ret = Matrix(x.sz1,y.sz2);for(int i=1; i<=x.sz1; i++){for(int j=1; j<=x.sz2; j++){for(int k=1; k<=y.sz2; k++){ret.a[i][j] = (ret.a[i][j]+x.a[i][k]*y.a[k][j])%(P-1ll);}}}return ret;
}
Matrix mquickpow(Matrix x,llong y)
{Matrix cur = x,ret; ret.uinit(x.sz);for(int i=0; y; i++){if(y&(1ll<<i)) {y-=(1ll<<i); ret = ret*cur;}cur = cur*cur;}return ret;
}
namespace BSGS
{const int B = 31595;map<llong,int> mp;void init(){llong bs = quickpow(G,B); llong j = 1ll;for(int i=0; i<=P; i+=B,j=(j*bs)%P){mp[j] = i;}}llong Logarithm(llong x){llong j = 1ll;for(int i=0; i<=B; i++,j=(j*G)%P){llong tmp = x*j%P;if(mp.count(tmp)){llong ret = (mp[tmp]-i+(P-1))%(P-1);return ret;}}return P-1;}
}
Matrix mA,mB,mC;
llong a[N+3],b[N+3];
int n; llong m,p,q,lq,lx;llong gcd(llong x,llong y) {return y==0 ? x : gcd(y,x%y);}
void exgcd(llong _a,llong _b,llong &_x,llong &_y)
{if(_b==0ll) {_x = 1ll,_y = 0ll; return;}exgcd(_b,_a%_b,_x,_y);llong tmp = _x; _x = _y; _y = tmp-(_a/_b)*_y;
}
llong CongruenceEquation(llong _a,llong _b,llong mod)
{llong g = gcd(_a,mod),x,y;exgcd(_a/g,mod/g,x,y);return (x*(_b/g)%mod+mod)%mod;
}int main()
{BSGS::init();scanf("%d",&n);for(int i=1; i<=n; i++) scanf("%I64d",&b[i]);scanf("%I64d",&m);mA = Matrix(1,n); mA.a[1][1] = 1ll;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];mC = mA*mquickpow(mB,m-n); p = mC.a[1][1]; scanf("%I64d",&q);lq = BSGS::Logarithm(q);if(lq%gcd(P-1,p)!=0) {printf("-1\n"); return 0;}lx = CongruenceEquation(p,lq,P-1);llong ans = quickpow(G,lx);printf("%I64d\n",ans);return 0;
}

发表于 2019-02-05 12:07 suncongbo 阅读(...) 评论(...) 编辑 收藏

刷新评论刷新页面返回顶部

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

  1. Codeforces 1106F Lunar New Year and a Recursive Sequence (线性代数、线性递推、数论、BSGS、扩展欧几里得算法)...

    哎呀大水题..我写了一个多小时..好没救啊.. 数论板子X合一? 注意: 本文中变量名称区分大小写. 题意: 给一个\(n\)阶递推序列\(f_k=\prod^{n}_{i=1} f_{k-i}^{b ...

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

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

  3. Codeforces 1106F Lunar New Year and a Recursive Sequence 矩阵快速幂,原根转化模意义下对数,BSGS

    文章目录 题意 题解 对数法转指数线性递推 原根与模意义下求对数 拔山盖世! 最终步骤 Problem Origin 狠搞了一个多星期,做出来之后仍然一知半解,写个博客重理思路. 题意 定义序列fff ...

  4. 数论练习二之BSGS算法——随机数生成器,Matrix,Lunar New Year and a Recursive Sequence,Fermat‘s Last Theorem

    [SDOI2013] 随机数生成器 description solution 肯定是非常想找一个通项公式来表示第nnn个数的 依据形式,考虑化成等比数列 xi+1+k=a(xi+k)=a⋅xi+b+t ...

  5. CF思维联系–CodeForces - 223 C Partial Sums(组合数学的先线性递推)

    ACM思维题训练集合 You've got an array a, consisting of n integers. The array elements are indexed from 1 to ...

  6. Recursive sequence HDU - 5950

    Recursive sequence HDU - 5950 题意: 给你一个式子:f[n]=2f[n-2]+f[n-1]+n4 给你f[1]和f[2],给你一个n,求f[n] f[1],f[2],n& ...

  7. [矩阵乘法/快速幂专题]Arc of Dream,Recursive sequence,233 Matrix,Training little cats

    矩阵快速幂习题 复习矩阵乘法及快速幂模板 乘法模板 快速幂模板 T1:Arc of Dream 题目 题解 code T2:Recursive sequence 题目 题解 code T3:233 M ...

  8. HDU 5950——Recursive sequence

    Recursive sequence 题意:给定起始的两个数a,b,求第n个数%mod 思路: 第一眼看出来是矩阵快速幂,不过当时没推出来(其实推了一半把自己给否定了) 正解是,根据二项式定理,对于f ...

  9. HDU 5950 Recursive sequence(矩阵快速幂)

    题目链接:Recursive sequence 题意:给出前两项和递推式,求第n项的值. 题解:递推式为:$F[i]=F[i-1]+2*f[i-2]+i^4$ 主要问题是$i^4$处理,容易想到用矩阵 ...

最新文章

  1. cin、cout的重载
  2. java 如何解密_java加密与解密
  3. Microsoft SQL Server 2000清理LDF日志
  4. DEV GridControl ID相同的行显示相同的颜色(当ID的值不确定时)
  5. python setup.py 指定文件到指定路径_linux下python安装到指定目录
  6. SparkMLlib回归算法之决策树
  7. 在 Windows 下部署 Go 语言环境
  8. 解决springmvc在multipart/form-data方式提交请求在过滤器Filter中获取不到参数的问题
  9. java控制台五子棋游戏
  10. 一张表搞懂各种 Docker 监控方案 - 每天5分钟玩转 Docker 容器技术(86)
  11. 分布式系统常用思想和技术
  12. 又见 Lucky Number
  13. 蘑菇租房java,租房经历总结-----我是如何2天找到合适租房的(房东直租)简单粗暴...
  14. 也来说是 AngularJS、 Angular 2、Angular 4 的区别
  15. K8S 1.18.0 以及KubeEdge 1.10.3 三机安装部署(含过程记录及遇到的报错和解决方法)
  16. Socket基本操作的C++封装--以及Socket通信实践
  17. 请把ios文件解压出来是什么意思_新款 | 扁平黑白浅色安卓 / 附改色教程 / iOS 版图稿预览...
  18. Xmanager要停用时,也可以手动卸载哦!
  19. java中使用pdfBox打印pdf;java web打印pdf;静默打印;jar程序打包成exe文件;exe4j的使用
  20. [转]论语新解(上篇)(2)

热门文章

  1. [java进阶]4.关键字throws和throw
  2. AutoLayout框架之序言
  3. LPSTR与char*的转换
  4. 在一个JS文件中包含中文字符串,通过innerHTML输出后中文乱码?
  5. Linux 0.00 的编译和运行
  6. 程序员面试系列——约瑟夫环
  7. 【❌❌深入浅出,九浅一深⭕⭕】《深入理解计算机系统》CSAPP
  8. PyTorch基础(八)----- torch.split()方法
  9. Mysql:kill命令之mysql杀死指定的进程(批操作)
  10. 互联网亿级日志实时分析平台,一个码农半小时就可以搞定,只因ELK