HDU 2814 斐波那契循环节+欧拉函数降幂
来源:互联网 发布:sql清除注册表 编辑:程序博客网 时间:2024/06/02 22:47
https://vj.xtuacm.cf/contest/view.action?cid=115#status//-/0/
求F(a^b)^(F(a^b)^(n-1))%c
a,b,n是longlong范围内的正整数
c是一个小于300的余数
思路:
不难发现c小于300是有意而为的
这里有两个定理:
1.在模c的状态下,斐波那契具有循环节性质,即F[a^b]=F[a^b%len] len即循环节
2.我们可以通过欧拉函数来进行降幂,即a^b%c=a^(b%φ(c)+φ(c))%c
F(a^b)^(F(a^b)^(n-1))%c
= F(a^b)^(F(a^b)^(n-1)%φ(c)+φ(c))%c
=F(a^b%loop1)^(F(a^b%loop2)^(n-1)%φ(c)+φ(c))%c
–》先将斐波那契循环节找到(loop1表示模c状态下的循环节,loop2表示模φ(c)状态下的循环节)
这样就可以直接用快速幂求了
分析:原式等价于求
有一点没明白的就是大多数题解的方案都是特判c=1与φ(c)=1的情况
,发现特美特判其实都一样c=1的时候就是0
φ(c)=1的时候c=1或c=2,可以直接输出a
/* 设t=a^b;G(1)=F[t]; 根据递推公式G(n)=G(n-1)^F[t];可知:G(2)=F[t]^F[t];G(3)=(F[t]^F[t])^F[t]=F[t]^(F[t]*F[t]); 这样我们能看出G(n)=F[t]^(F[t]^(n-1)); 首先我们在这里要先解决F[t]的值,由于a,b的值都比较大,所以求a^b是不现实的(java你可以试试) 但是我们取余的C是比较小的,所以可以使用循环节来求出F[t]%C的值,设A=F[t]%C; 接下来求A^(F[t]^(n-1))%C的值,这里还是由于F[t]的值是没有办法求的,所以需要用到取余来简化计算, 那么我们会想到费马小定理,欧拉公式,但是这里没说C是素数,所以要用到万能公式来求解, 即首先要求出φ(C),然后再求出循环节,得到F[t]%φ(C)的值,这样我们就能求解了。 注意C=1和欧拉函数值为1的情况。 */ #include <iostream>#include <cstdio>#include <cmath>#include <cstring>#define ll unsigned long longll f[5500];using namespace std;int sch(int c){ int loop; f[0]=0,f[1]=1; for(int i=2; i<2005; i++) { f[i]=(f[i-1]%c+f[i-2]%c)%c; if(f[i-1]==0&&f[i]==1) { loop=i; break; } } return loop-1;}int phi(int n){ int rea=n; for(int i=2; i*i<=n; i++) { if(n%i==0) { rea=rea-rea/i; while(n%i==0) n=n/i; } } if(n>1) rea=rea-rea/n; return rea;}ll multi(ll a,ll b,ll mod){ ll ans=0; while(b) { if(b&1) ans=(ans+a)%mod; b>>=1; a=(a+a)%mod; } return ans;}ll quick_pow(ll m,ll n,ll mod){ ll ans=1; m=m%mod; while(n) { if(n&1)ans=multi(ans,m,mod); n>>=1; m=multi(m,m,mod); } return ans;}int main(){ int t,c; ll a,b,n; scanf("%d",&t); int tt=1; while(t--) { scanf("%I64u %I64u %I64u %d",&a,&b,&n,&c); if(c==1) { printf("Case %d: 0\n",tt++); continue; } int p=phi(c); int loop1=sch(c); ll t1=quick_pow(a,b,loop1); ll tmp1=f[t1]%c; int loop2=sch(p); ll t2=quick_pow(a,b,loop2); ll tmp2=f[t2]%p; tmp2=quick_pow(tmp2,n-1,p); tmp2+=p; tmp1=quick_pow(tmp1,tmp2,c); printf("Case %d: %I64u\n",tt++,tmp1); } return 0;}
阅读全文
0 0
- HDU 2814 斐波那契循环节+欧拉函数降幂
- HDU 2814 斐波那契循环节+欧拉函数降幂
- hdu-2814-Interesting Fibonacci-斐波那契循环节
- Hdu 4335 What is N? 欧拉函数降幂公式 + 循环节
- hdu 4549 M斐波那契数列 【矩阵+快速幂+欧拉定理】
- HDU 3978 斐波那契循环节
- HDU 4794 Arnold 斐波那契数列循环节
- HDU 4794 斐波那契数列循环节
- HDU 5728 PowMod (欧拉函数+指数循环节)
- hdu -2837(指数循环节+欧拉函数)
- hdu4549 M斐波那契数列 【矩阵快速幂+快速幂+欧拉函数降次】
- 51nod 1195 斐波那契数列的循环节【斐波那契数列&&二次剩余&&欧拉判定准则】
- hdu 2837 Calculation【欧拉函数,快速幂求指数循环节】
- HDU 2814 斐波那契数列的循环节问题
- hdu 5451 Best Solver -广义斐波那契+矩阵快速幂+共轭构造+循环节
- HDOJ M斐波那契数列 4549【矩阵快速幂+快速幂+费马小定理+欧拉函数】
- HDU 3977 求斐波那契循环节
- HDU 5895 Mathematician QSC (矩阵快速幂 + 逆元应用 + 指数循环节 + 欧拉函数)
- 如何进行字符串解析,并打印需要的字符串
- java基础学习
- Intellij UML Support插件介绍 及 Android Context继承关系
- 免费馅饼||HDU1176
- 获取字符串高度或宽度
- HDU 2814 斐波那契循环节+欧拉函数降幂
- win7 64位VS2012生成MSVCP110D.dll错误,调运行库为多线程/mtd
- H.264中的SPS和PPS
- 算法类面试题解析——美团2016校招:棋子翻转
- Super Jumping! Jumping! Jumping! --DP
- linux编程---进程通信中,利用socketpair实现子进程间通信
- WebRTC实时通信系列教程6 使用RTCDataChannel传输数据
- 解决PopupWindow在7.0以上位置不正确的bug
- 代码 框架学习系列 mybatis 第八篇 mybatis开发dao的方式