2019牛客多校第五场 generator 1——广义斐波那契循环节&&矩阵快速幂
理论部分
二次剩余
在数论中,整数 $X$ 对整数 $p$ 的二次剩余是指 $X^2$ 除以 $p$ 的余数。
当存在某个 $X$,使得式子 $X^2 \equiv d(mod \ p)$ 成立时,称“ $d$ 是模 $p$ 的二次剩余”
当对任意 $X$,$X^2 \equiv d(mod \ p)$ 都不成立时,称“ $d$ 是模 $p$ 的二次非剩余”
矩阵的相似对角化
相似矩阵:对于矩阵 $A$ 和 $B$,若存在可逆矩阵 $P$,使得 $P^{-1}AP=B$,则称 $A$ 相似于 $B$,记作 $A\sim B$。
矩阵可对角化是指与对角矩阵相似,即 $P^{-1}AP = diag(\lambda _1, \lambda _2,...,\lambda _n)$
定理:$n$ 阶矩阵 $A$ 与对角矩阵相似的充要条件是 $A$ 有 $n$ 个线性无关的特征向量。简单的判断就是 $|A| \neq 0$.
分析
来源于 acdreamers 的广义Fibonacci数列找循环节,这里只是梳理一下。
将递推式表示成转移矩阵的形式,相当于只需找到转移矩阵的周期。
即求最小的 $n$,使得
$${\begin{bmatrix} a & b\\ 1 & 0 \end{bmatrix}}^n(mod \ p) = \begin{bmatrix} 1 & 0\\ 0 & 1 \end{bmatrix}$$
我们可以找到一个满足条件的 $n$,然后枚举其因子。
设 $A$ 相似于 $D$,$A$ 的特征根分别为 $\lambda _1,\lambda _2$.
则D为
$D = \begin{bmatrix} \lambda _1 & 0\\ 0 & \lambda _2 \end{bmatrix}$
因为 $A^n = T^{-1}D^nT$,所以 $D^n \equiv I(mod \ p)$ 时,$D^n \equiv I(mod \ p)$
由于$$D^n = {\begin{bmatrix} \lambda _1 & 0\\ 0 & \lambda _2 \end{bmatrix}}^n = \begin{bmatrix} \lambda _1^n & 0\\ 0 & \lambda _2^n \end{bmatrix}(mod \ p) = I$$
于是 $\lambda _1^n\equiv 1(mod \ p),\ \lambda _2^n\equiv 1(mod \ p)$.
如何找到 $n$ 呢?
直接上结论吧!(看不懂了555)
设 $\Delta = a^2+4b$
- 若 $\Delta$ 是 $p$ 的二次剩余,$n=p-1$
- 若 $\Delta$ 是 $p$ 的二次非剩余,$n=(p+1)(p-1)$
- 若 $\Delta=p$,则无法相似化。幸好题目不会出现这种情况
上述结论还是针对 $p$ 为素数,$p$ 为合数呢?
首先,质因数分解 $p=p_1^{a_1}p_2^{a_2}...p_k^{a_k}$,
设 $g(x)$ 为模 $x$ 时循环节长度,有结论 $g(p_i^{a_i}) = p_i^{a_1-1} g(p_i)$
所以
$$
\begin{aligned}
g(x) & =g(p_1^{a_1}p_2^{a_2}...p_k^{a_k})\\
&= p_1^{a_1-1} g(p_1) \cdot p_2^{a_2-1} g(p_2) ... p_k^{a_k-1} g(p_k)\\
&= (p / p_1p_2... p_k) g(p_1)g(p_2) ... g(p_k)
\end{aligned}$$
实现
二次剩余我又不会判断,直接当作 $(p+1)(p-1)$,大不了多个倍数。
按道理最小的循环节不是 $n$,而是 $n$ 的因数,感觉分解再判断挺麻烦的,不管了,大不了多个倍数。
#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 ;
}
参考链接:
1. 分析: https://blog.csdn.net/acdreamers/article/details/25616461
2. 代码:https://www.cnblogs.com/LMCC1108/p/11286388.html
2019牛客多校第五场 generator 1——广义斐波那契循环节&&矩阵快速幂的更多相关文章
- 2019牛客多校第五场generator2——BSGS&&手写Hash
题目 几乎原题 BZOJ3122题解 分析 先推一波公式,然后除去特殊情况分类讨论,剩下就是形如 $a^i \equiv b(mod \ p)$ 的方程,可以使用BSGS算法. 在标准的BSGS中,内 ...
- 2019牛客多校第五场F maximum clique 1 最大独立集
题意:给你n个数,现在让你选择一个数目最大的集合,使得集合中任意两个数的二进制表示至少有两位不同,问这个集合最大是多大?并且输出具体方案.保证n个数互不相同. 思路:容易发现,如果两个数不能同时在集合 ...
- 2019牛客多校第五场G-subsequence 1 DP
G-subsequence 1 题意 给你两个字符串\(s.t\),问\(s\)中有多少个子序列能大于\(t\). 思路 令\(len1\)为\(s\)的子序列的长度,\(lent\)为\(t\)的长 ...
- 2019牛客多校第五场 B - generator 1 矩阵快速幂+十倍增+二进制倍增优化
B - generator 1 题意 给你\(x_{0}.x_{1}.a.b.b.mod\),根据\(x_{i} = a*x_{i-1} + b*x_{i-2}\)求出\(x_{n}\) 思路 一般看 ...
- 2019牛客多校第五场H - subsequence 2 拓扑
H - subsequence 2 题意 要你使用前\(m\)个小写字母构造一个长度为\(n\)的字符串 有\(m*(m-1)/2\)个限制条件: \(c_{1} .c_{2}. len\):表示除去 ...
- 2019牛客多校第五场B-generator 1(矩阵快速幂)
generator 1 题目传送门 解题思路 矩阵快速幂.只是平时的矩阵快速幂是二进制的,这题要用十进制的快速幂. 代码如下 #include <bits/stdc++.h> #defin ...
- 2019 牛客多校第五场 B generator 1
题目链接:https://ac.nowcoder.com/acm/contest/885/B 题目大意 略. 分析 十进制矩阵快速幂. 代码如下 #include <bits/stdc++.h& ...
- 2019牛客多校第五场 G subsequence 1 dp+组合数学
subsequence 1 题意 给出两个数字串s,t,求s的子序列中在数值上大于t串的数量 分析 数字大于另一个数字,要么位数多,要么位数相同,字典序大,位数多可以很方便地用组合数学来解决,所以只剩 ...
- 2019牛客多校第五场 F maximum clique 1 状压dp+最大独立集
maximum clique 1 题意 给出一个集合s,求每个子集的最大独立集的权值和(权值是独立集的点个数) 分析 n比较小,一股浓浓的暴力枚举每一个子集的感觉,但是暴力枚举模拟肯定会T,那么想一想 ...
随机推荐
- Mac10.14.6安装Python3
换了台新电脑, 记录一下Python3的安装过程. 1.检查现有版本的python. 因为Mac的系统以来python2, 所以python肯定是有的, 因为依赖, 所以安装了python3, 也不可 ...
- [转帖]华为鲲鹏云服务器实战:华为云鲲鹏KC1实例 vs. 阿里云G5实例
鲲鹏云服务器实战:华为云鲲鹏KC1实例 vs. 阿里云G5实例 https://m.ithome.com/html/444828.htm 2019-09-12 15:25IT之家 (阿迷) 今年一月份 ...
- Python_Modbus_RTU_通讯Demo
之前利用Python进行Modbus_TCP进行数据接收,本次需要利用串口进行数据传输,学习Modbus_RTU的简单实现 首先要在创建两个虚拟串口,利用VSPD工具即可.在一台电脑上实现数据的发送和 ...
- Python面试题集合带答案
目录 Python基础篇 1:为什么学习Python 2:通过什么途径学习Python 3:谈谈对Python和其他语言的区别 Python的优势: 4:简述解释型和编译型编程语言 5:Python的 ...
- JS OOP 概述
JS面向对象,大致内容 1.面向对象的基础 2.深入认识JS的函数 3.JS类的实现 4JS中共有成员,私有成员和静态成员 5.JS的反射 6.JS的继承 7.JS实现抽象类 8.JS事件设计模式 9 ...
- ubuntu14.04
14.10显卡驱动有问题 1.恢复启动引导菜单:启动盘 -> 运行到分区之前,不要分区 -> shift+f10 进入dos -> bootsec /fixmbr ->关闭重启 ...
- 客户端相关知识学习(十二)之iOS H5交互Webview实现localStorage数据存储
前言 最近有一个需求是和在app中前端本地存储相关的,所以恶补了一下相关知识 webView开启支持H5 LocalStorage存储 有些时候我们发现写的本地存储没有起作用,那是因为默认WebVie ...
- luogu题解 P3950部落冲突--树链剖分
题目链接 https://www.luogu.org/problemnew/show/P3950 分析 大佬都用LCT,我太弱只会树链剖分 一个很裸的维护边权树链剖分题.按照套路,对于一条边\(< ...
- python打印表格式数据-星号或注释
python打印表格式数据,留出正确的空格,格式化打出 代码如下: def printPicnic(itemsDict,leftWidth,rightWidth): print('PICNIC ITE ...
- vue学习(6)-路由(导入包;创建子组件;创建路由对象)传参,子路由,多个组件
后端路由:对于普通的网站,所有的超链接都是URL地址,所有的URL地址都对应服务器上对应的资源 前端路由:对于单页面应用程序来说,主要通过URL中的hash(#号)来实现不同页面之间的切换(不会刷新页 ...