HDU 5451——递推式&&循环节
题意
设 $y = (5+2\sqrt 6)^{1+2^x}$,给出 $x, M$($0\leq x \leq 2^{32}, M \leq 46337$),求 $[y]\%M$.
分析
由通项推递推式??
设 $A_n = (5 + 2\sqrt 6)^n, B_n = (5 - 2\sqrt 6)^n,C_n = A_n + B_n$,
显然 $C_n$ 是整数,且 $B_n$ 是小于1的,所以答案就是 $C_n - 1$.
通过推导:
$C_n = A_n + B_n = (5+2\sqrt6)^n + (5-2\sqrt6)^n$
$C_{n+1} = A_{n+1} + B_{n+1} = (5+2\sqrt6)(5+2\sqrt6)^n + (5-2\sqrt6)(5-2\sqrt6)^n$
$C_{n+2} = A_{n+2} + B_{n+2} = (49+20\sqrt6)(5+2\sqrt6)^n + (49-20\sqrt6)(5-2\sqrt6)^n$,
观察得 $C_{n+2} = 10C_{n+1} - C_n$
写成矩阵快速幂的形式,即
$$\begin{bmatrix} C_n\\ C_{n-1} \end{bmatrix} = {\begin{bmatrix} 10 & -1\\ 1 & 0 \end{bmatrix}}^{n-1}\begin{bmatrix} C_1\\ C_0 \end{bmatrix}$$
幂太大,直接用快速幂肯定TLE。
我们可以找循环节,
由于模和转移矩阵是确定的,可以暴力打表找规律。
也可以用结论,因为 $M$ 为素数,存在循环节 $(M+1)(M-1)$。这不一定是最小的循环节,可以枚举其因子找到最小的循环节。
- #include<bits/stdc++.h>
- using namespace std;
- typedef long long ll;
- const int N=+;
- ll x0,x1,a,b,n,mod;
- char s[N];
- const int maxn = + ; //p最为2e9,不会有两个超过1e5的质因数
- int prime[maxn], pcnt; //prime[i]表示第i个素数
- bool is_prime[maxn + ]; //is_prime[i]为true表示i是素数
- int sieve(int n)
- {
- int cnt = ;
- for (int i = ; i <= n; i++) is_prime[i] = true;
- is_prime[] = is_prime[] = false;
- for (ll i = ; i <= n; i++)
- {
- if (is_prime[i])
- {
- prime[cnt++] = i;
- for (ll j = i * i; j <= n; j += i) is_prime[j] = false; //i * i可能爆int
- }
- }
- return cnt;
- }
- ll solve(ll x){
- ll ans1=,ans2=,xx=x;
- for(int i=;i<pcnt;i++){
- if(1ll*prime[i]*prime[i]>x) break;
- if(x%prime[i]==){
- ans1*=(prime[i]-)*(prime[i]+);
- ans2*=prime[i];
- while(x%prime[i]==) x/=prime[i];
- }
- }
- if(x>){
- ans1*=(x-)*(x+);
- ans2*=x;
- }
- return xx/ans2*ans1;
- }
- ll qmul(ll x,ll y,ll p){ //快速乘
- x%=p;
- y%=p;
- ll ans=;
- while(y){
- if(y&){
- ans+=x;
- if(ans>=p) ans-=p; //这样写不能有负数
- }
- x<<=;
- if(x>=p) x-=p;
- y>>=;
- }
- return ans;
- }
- struct Mat{
- int r,c;
- ll m[][];
- Mat(){
- memset(m,,sizeof(m));
- }
- };
- Mat mmul(Mat x,Mat y,ll p){
- Mat ans;
- ans.r=x.r;
- ans.c=y.c;
- for(int i=;i<x.r;i++)
- for(int k=;k<x.c;k++)
- for(int j=;j<y.c;j++){
- ans.m[i][j]+=qmul(x.m[i][k],y.m[k][j],p);
- if(ans.m[i][j]>=p) ans.m[i][j]-=p;
- }
- return ans;
- }
- Mat mpow(Mat x,ll y,ll p){
- Mat ans;
- ans.r=x.r;
- ans.c=x.c;
- for(int i=;i<ans.c;i++) ans.m[i][i]=;
- while(y){
- if(y&) ans=mmul(ans,x,p);
- x=mmul(x,x,p);
- y>>=;
- }
- return ans;
- }
- int main(){
- pcnt = sieve();
- while(scanf("%lld%lld%lld%lld",&x0,&x1,&a,&b) == ){
- scanf("%s%lld",s,&mod);
- ll lop=solve(mod); //循环节长度
- n=;
- int lens=strlen(s);
- for(int i=;i<lens;i++){
- n=qmul(n,,lop)+s[i]-'';
- if(n>=lop) n-=lop;
- }
- Mat A,T;
- A.r=; A.c=;
- A.m[][]=x1; A.m[][]=x0;
- T.r=; T.c=;
- T.m[][]=a; T.m[][]=b; T.m[][]=;
- if(n>){
- T=mpow(T,n-,mod);
- A=mmul(T,A,mod);
- }
- printf("%lld\n",A.m[][]);
- }
- return ;
- }
参考链接:https://www.cnblogs.com/addf/p/4834108.html
HDU 5451——递推式&&循环节的更多相关文章
- "红色病毒"问题 HDU 2065 递推+找循环节
题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=2065 递推类题目, 可以考虑用数学方法来做, 但是明显也可以有递推思维来理解. 递推的话基本就是状态 ...
- HDU 1757 A Simple Math Problem 【矩阵经典7 构造矩阵递推式】
任意门:http://acm.hdu.edu.cn/showproblem.php?pid=1757 A Simple Math Problem Time Limit: 3000/1000 MS (J ...
- hdu 1757 A Simple Math Problem (构造矩阵解决递推式问题)
题意:有一个递推式f(x) 当 x < 10 f(x) = x.当 x >= 10 f(x) = a0 * f(x-1) + a1 * f(x-2) + a2 * f(x-3) + ...
- HDU - 2604 Queuing(递推式+矩阵快速幂)
Queuing Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Su ...
- hdu 5950 Recursive sequence 递推式 矩阵快速幂
题目链接 题意 给定\(c_0,c_1,求c_n(c_0,c_1,n\lt 2^{31})\),递推公式为 \[c_i=c_{i-1}+2c_{i-2}+i^4\] 思路 参考 将递推式改写\[\be ...
- ZOJ 3182 HDU 2842递推
ZOJ 3182 Nine Interlinks 题目大意:把一些带标号的环套到棍子上,标号为1的可以所以操作,标号i的根子在棍子上时,只有它标号比它小的换都不在棍子上,才能把标号为i+1的环,放在棍 ...
- 矩阵乘法&矩阵快速幂&矩阵快速幂解决线性递推式
矩阵乘法,顾名思义矩阵与矩阵相乘, 两矩阵可相乘的前提:第一个矩阵的行与第二个矩阵的列相等 相乘原则: a b * A B = a*A+b*C a*c+b*D c d ...
- P1067Warcraft III 守望者的烦恼(十大矩阵问题之七求递推式)
https://vijos.org/p/1067 守望者-warden,长期在暗夜精灵的的首都艾萨琳内担任视察监狱的任务,监狱是成长条行的,守望者warden拥有一个技能名叫“闪烁”,这个技能可以把她 ...
- Tyche 2191 WYF的递推式
题目描述 WYF手中有这样一条递推式 WYF并不是想让你帮他做出结果,事实上,给定一个n,他能够迅速算出Fn.WYF只是想单纯的考验一下读者们. 输入描述 仅一行,三个整数N,F1,P 输出描述 仅一 ...
随机推荐
- [转帖]【JVM 知识体系框架总结】
[JVM 知识体系框架总结] https://www.cnblogs.com/mousycoder/p/11612448.html JVM 内存分布 线程共享数据区:方法区->类信息,静态变量堆 ...
- yum源出问题,rpmdb: BDB0113 Thread/process 17276/140338032428864 failed: BDB1507 Thread died in Berkeley DB library
yum源出问题 cd /var/lib/rpm rm -f *db.* rpm --rebuilddb 重构了之后就可以用了
- oracle多表关联查询和子查询
oracle多表关联查询和子查询 一.多表关联查询 例子: SQL> create table student1 ( sid ), sname ), sage )); Table created ...
- VUE创建项目
Vue Cli项目搭建 vue项目需要自建服务器:node 什么是node: 用C++语言编写,用来运行JavaScript语言 node可以为前端项目提供server (包含了socket) ...
- python学习——while True的用法
在学习过程中,经常能遇到采用while True的用法.下面以一个例子进行说明: 建立一个用户登录系统,用户输入用户名和密码,如果正确就可以进入系统. 1.我自己最开始的写法: d = {} #数据库 ...
- Python笔记002-Python编程基础概念
第二章(1):Python编程基础概念 1. Python 程序的构成 Python 程序有模块组成.一个模块对应 Python 源文件,一般后缀名是:.py. 模块有语句组成.运行 Python程序 ...
- 使用Duilib开发Windows软件(4)——消息传递
云信Duilib中没有窗体类的函数可以用来直接收取到所有控件的事件,每个控件都可以单独设置自己的事件处理函数,一般在InitWindow方法中初始化各个控件的事件处理函数. 每个控件都有许多形如Att ...
- spring中使用动态代理(AOP)
spring是整合了BGLIB和JDK两种动态代理 示例:使用CGLIB代理 public class MyCar { private String color = "blue"; ...
- scratch少儿编程——03、动作:运动的开始,游戏的基础。
各位小伙伴大家好: 从这一期开始我们来学Scratch的具体操作. 第一季我们会从每一个脚本模块开始.一个程序块一个程序块去操作,感受它的效果. 今天我们来一起学习程序区的脚本类动作模块的指令. 动作 ...
- element-ui 时间设置 获取固定的时间格式
<el-date-picker v-model="time1" type="daterange" start-placeholder="开始日期 ...