https://blog.csdn.net/acdreamers/article/details/10983813(Fib数模n的循环节的长度)
https://blog.csdn.net/ACdreamers/article/details/25616461(广义Fibonacci数列找循环节)
求Fib数模n的最小循环节的长度的方法:
1.把n素因子分解,即
2.分别计算Fib数模每个的循环节长度,假设长度分别是
Fib数模的最小循环节长度等于,
其中表示Fib数模素数的最小循环节长度。
求的方法论:(详细证明见第二篇博文)
设,那么分情况讨论,注意p为奇素数,需特判p==2
①是模的二次剩余时,枚举的因子
②是模的二次非剩余时,枚举的因子
③找最小的因子,使得
成立。
3.Fib模n的循环节长度
求Fib数模n的循环节(非最小)的长度的方法:
注意到,上述方法中,无论何种情况,一定是的因子
那么,Fib数模的循环节长度,一定是的因子,暴力的做法
即为所求,也不求lcm了,循环节最多变为原数的完全平方倍
2019牛客暑期多校训练营(第五场)B.generator 1
求广义Fibonacci数列的1e(1e6)项%mod的值,mod在(1e9,2e9]之间
法一:变二进制矩阵快速幂为十进制矩阵快速幂,每一位进行一次快速幂
法二:求循环节,将1e(1e6)模循环节化为ll可表示的幂次,再进行快速幂
减少取模次数,可以卡过,也可以用2 4 8的倍增 用8+2 去凑10次 就不用写快速幂了
#include
#include
#include
using namespace std;
const int MAXN = 2;
const int N=1e6+10;
typedef long long ll;
int MOD;
char s[N];
ll x0,x1,a,b;
struct mat {
ll c[MAXN][MAXN];
int m, n;
mat(){
memset(c, 0, sizeof(c));
m=n=MAXN;
}
mat(int a, int b) : m(a), n(b) {
memset(c, 0, sizeof(c));
}
void clear(){
memset(c, 0, sizeof(c));
}
mat operator * (const mat& temp) {
mat ans(m, temp.n);
for (int i = 0; i < m; i ++)
for (int j = 0; j < temp.n; j ++)
{
for (int k = 0; k < n; k ++)
ans.c[i][j] += c[i][k] * temp.c[k][j];
ans.c[i][j]%=MOD;
}
return ans;
}
friend mat operator ^(mat M, int n)
{
mat ans(M.m, M.m);
for (int i = 0; i < M.m; i ++)
ans.c[i][i] = 1;
while (n > 0) {
if (n & 1) ans = ans * M;
M = M * M;
n >>= 1;
}
return ans;
}
}bs,res;
int main()
{
scanf("%lld%lld%lld%lld",&x0,&x1,&a,&b);
scanf("%s%d",s,&MOD);
bs.c[0][0]=a;bs.c[0][1]=b;
bs.c[1][0]=1;
res.c[0][0]=res.c[1][1]=1;
int len=strlen(s);
ll now=0;
for(int i=len-1;i>=0;--i)
{
int v=s[i]-'0';
res=res*(bs^v);//res*s[i]倍的基底
bs=bs^10;//基底扩大为原来10次方的基底
}
printf("%lld\n",(res.c[1][0]*x1%MOD+res.c[1][1]*x0%MOD)%MOD);
return 0;
}
#include
#include
#include
#include
#include
using namespace std;
#define maxn 45000
typedef __int128 LL;
const int M=1e6+10;
LL f0,f1,a,b;
LL N,P;
LL prime[maxn];
LL fac[maxn];
char s[M];
inline __int128 read()
{
long long X=0,w=0; char ch=0;
while(!isdigit(ch)) {w|=ch=='-';ch=getchar();}
while(isdigit(ch)) X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
return w?-X:X;
}
inline void print(__int128 x)
{
if(x<0){putchar('-');x=-x;}
if(x>9) print(x/10);
putchar(x%10+'0');
}
void Prime(){
memset(prime,0,sizeof(prime));
for(int i=2;i=mod){
ans.m[i][j]-=mod;
}
}
}
}
return ans;
}
void init(){
memset(E.m,0,sizeof(E.m));
memset(D.m,0,sizeof(D.m));
D.m[0][0]=a;D.m[0][1]=b;
D.m[1][0]=1;
for(int i=0;i<2;i++){
E.m[i][i]=1;
}
Prime();
}
Matrix Pow(Matrix A,LL e,LL mod){
Matrix ans=E;
while(e){
if(e&1){
ans=Multi(ans,A,mod);
}
A=Multi(A,A,mod);
e>>=1;
}
return ans;
}
LL Pow(LL a,LL b,LL mod){
LL ans=1;
while(b){
if(b&1){
ans=(ans*a)%mod;
}
a=(a*a)%mod;
b>>=1;
}
return ans;
}
LL get_fib(LL n,LL mod)
{
if(mod==1) return 0;
if(n==0)return f0%mod;
Matrix ans=Pow(D,n-1,mod);
return (ans.m[0][0]*f1%mod+ans.m[0][1]*f0%mod)%mod;
}
LL find_loop(LL n)
{
get_factors(n);
LL ans=1;
for(int i=0;i