• [WC2021] 斐波那契——数论、斐波那契数列


    [WC2021] 斐波那契

    题解

    这里不得不向 Tiw 神下跪~
    一道黑题被他讲成一道蓝题难度
    根本不会做的我瞬间感觉自己降智了好多

    首先发现我们要解决的是满足这个式子:
    a f n − 1 + b f n = 0    (   m o d    m ) af_{n-1}+bf_n=0\,\,(\bmod\, m) afn1+bfn=0(modm)的最小的 n n n

    我们可以先处理一下,令 c = gcd ⁡ ( a , b , m ) , a ′ = a c , b ′ = b c , m ′ = m c c=\gcd(a,b,m),a'=\frac{a}{c},b'=\frac{b}{c},m'=\frac{m}{c} c=gcd(a,b,m),a=ca,b=cb,m=cm,然后有如下性质:
    gcd ⁡ ( gcd ⁡ ( a ′ , m ′ ) , gcd ⁡ ( b ′ , m ′ ) ) = 1 gcd ⁡ ( f n , f n − 1 ) = 1 \gcd(\gcd(a',m'),\gcd(b',m'))=1\\ \gcd(f_n,f_{n-1})=1 gcd(gcd(a,m),gcd(b,m))=1gcd(fn,fn1)=1因为取模 m ′ m' m 不影响与 m ′ m' m gcd ⁡ \gcd gcd,由 gcd ⁡ ( a ′ f n − 1 , m ′ ) = gcd ⁡ ( b ′ f n , m ′ ) \gcd(a'f_{n-1},m')=\gcd(b'f_n,m') gcd(afn1,m)=gcd(bfn,m) 可得:
    gcd ⁡ ( a ′ , m ′ gcd ⁡ ( f n − 1 , m ′ ) ) gcd ⁡ ( f n − 1 , m ′ ) = gcd ⁡ ( b ′ , m ′ ) gcd ⁡ ( f n , m ′ gcd ⁡ ( b ′ , m ′ ) ) ⇒ gcd ⁡ ( f n − 1 , m ′ ) gcd ⁡ ( f n , m ′ gcd ⁡ ( b ′ , m ′ ) ) = gcd ⁡ ( b ′ , m ′ ) gcd ⁡ ( a ′ , m ′ gcd ⁡ ( f n − 1 , m ′ ) ) \gcd(a',\frac{m'}{\gcd(f_{n-1},m')})\gcd(f_{n-1},m')=\gcd(b',m')\gcd(f_n,\frac{m'}{\gcd(b',m')})\\ \Rightarrow \frac{\gcd(f_{n-1},m')}{\gcd(f_n,\frac{m'}{\gcd(b',m')})}=\frac{\gcd(b',m')}{\gcd(a',\frac{m'}{\gcd(f_{n-1},m')})}\\ gcd(a,gcd(fn1,m)m)gcd(fn1,m)=gcd(b,m)gcd(fn,gcd(b,m)m)gcd(fn,gcd(b,m)m)gcd(fn1,m)=gcd(a,gcd(fn1,m)m)gcd(b,m)因为两边的分式的分子分母都互质,所以两边都是最简分式,有 gcd ⁡ ( f n , m ′ gcd ⁡ ( b ′ , m ′ ) ) = gcd ⁡ ( a ′ , m ′ gcd ⁡ ( f n − 1 , m ′ ) ) gcd ⁡ ( f n − 1 , m ′ ) = gcd ⁡ ( b ′ , m ′ ) \gcd(f_n,\frac{m'}{\gcd(b',m')})=\gcd(a',\frac{m'}{\gcd(f_{n-1},m')})\\ \gcd(f_{n-1},m')=\gcd(b',m') gcd(fn,gcd(b,m)m)=gcd(a,gcd(fn1,m)m)gcd(fn1,m)=gcd(b,m)而我们需要的只有第二条。

    g = gcd ⁡ ( b ′ , m ′ ) g=\gcd(b',m') g=gcd(b,m),那么有 − a ′ b ′ g = f n f n − 1 g    (   m o d    m ′ g ) \frac{-a'}{\frac{b'}{g}}=\frac{f_n}{\frac{f_{n-1}}{g}}\,\,(\bmod\, \frac{m'}{g}) gba=gfn1fn(modgm),此时分母与模数互质,可以求逆元。

    于是就得到一种做法:先预处理,枚举所有可能的 m ′ m' m m m m 的因子),然后枚举斐波那契数列,把相邻两项按 g = gcd ⁡ ( f n − 1 , m ′ ) g=\gcd(f_{n-1},m') g=gcd(fn1,m) 分类,每一类用 map 记录到达一种 f n f n − 1 g \frac{f_n}{\frac{f_{n-1}}{g}} gfn1fn 值的最小的 n n n。由于斐波那契在模意义下循环节长度是 O ( 模 数 ) O(模数) O() 的,所以预处理复杂度大概是 m m m 的因子的和带个 log ⁡ \log log,不超过 O ( m log ⁡ 2 m ) O(m\log^2m) O(mlog2m)

    询问直接找到对应的 m ′ m' m 对应的类再在 map 里查询即可。

    代码

    #include<bits/stdc++.h>//JZM yyds!!
    #define ll long long
    #define lll __int128
    #define uns unsigned
    #define fi first
    #define se second
    #define IF (it->fi)
    #define IS (it->se)
    #define END putchar('\n')
    #define lowbit(x) ((x)&-(x))
    #define inline jzmyyds
    using namespace std;
    const int MAXN=114514;
    const ll INF=1e18;
    ll read(){
    	ll x=0;bool f=1;char s=getchar();
    	while((s<'0'||s>'9')&&s>0){if(s=='-')f^=1;s=getchar();}
    	while(s>='0'&&s<='9')x=(x<<1)+(x<<3)+(s^48),s=getchar();
    	return f?x:-x;
    }
    int ptf[50],lpt;
    void print(ll x,char c='\n'){
    	if(x<0)putchar('-'),x=-x;
    	ptf[lpt=1]=x%10;
    	while(x>9)x/=10,ptf[++lpt]=x%10;
    	while(lpt>0)putchar(ptf[lpt--]^48);
    	if(c>0)putchar(c);
    }
    int Q,m;
    unordered_map<int,unordered_map<int,int> >mp[MAXN];
    ll gcd(ll a,ll b){return !b?a:gcd(b,a%b);}
    ll exgcd(ll a,ll b,ll&x,ll&y){
    	if(!b)return x=1,y=0,a;
    	ll d=exgcd(b,a%b,y,x);
    	return y-=a/b*x,d;
    }
    ll inv(ll a,ll p){
    	ll x,y,d=exgcd(a,p,x,y);
    	if(d!=1)return 1145141919810;
    	return (x%p+p)%p;
    }
    int main()
    {
    	Q=read(),m=read(),mp[1][1][0]=2;
    	for(int x=2;x<=m;x++)if(m%x==0){
    		ll a=1,b=1;
    		for(int i=2;;i++,swap(a,b),(b+=a)%=x){
    			ll d=gcd(a,x),c=b*inv(a/d,x/d)%(x/d);
    			if(mp[x][d].count(c))break;
    			mp[x][d][c]=i;
    		}
    	}
    	while(Q--){
    		ll a=read(),b=read();
    		if(!a){print(0);continue;}
    		if(!b){print(1);continue;}
    		ll d=gcd(gcd(a,b),m),k=m/d;
    		a/=d,b/=d,d=gcd(b,k);
    		ll c=(m-a)*inv(b/d,k/d)%(k/d);
    		auto it=mp[k][d].find(c);
    		if(it!=mp[k][d].end())print(IS);
    		else print(-1);
    	}
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
  • 相关阅读:
    面向对象实验一 类的建立与应用
    面试了无数公司才总结的JAVA面试题(含答案),搞定80%以上的技术面!
    Spring Cloud 与微服务学习总结(17)—— SpringCloud Gateway API 接口安全设计(加密 、签名、安全)
    Hbase java API与过滤器
    蓝桥杯-缩位求和
    MediaBox助力企业一站式获取音视频能力
    VScode 调试python程序,debug状态闪断问题的解决方法
    Net6.0项目发布到IIS 503
    RabbitMQ 教你如何创建虚拟主机
    【C++】C++ 引用详解 ① ( 变量的本质 - 引入 “ 引用 “ 概念 | 引用语法简介 | 引用做函数参数 | 复杂类型引用做函数参数 )
  • 原文地址:https://blog.csdn.net/weixin_43960287/article/details/125464953