hdu 3221 Brute-force Algorithm (09上海区域赛)欧拉定理
来源:互联网 发布:阿里云当机 编辑:程序博客网 时间:2024/06/03 03:04
题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=3221
思路 首先列出n比较小的一些,找到规律,指数就是fibonacci数列,也不难由函数递归的形式猜出。
然后如果n<=33 int 范围内是放得下的, 可以直接快速幂。
但是如果n很大,(f[45] 就要超过int了) 这样就得用欧拉定理了 ,是用a和m不互素的那种,但是不可能存得下那么多数,所以我们基于线性递推数列,模上一个数后必然出现周期这样的结论,猜想会在不超过数组范围内出现周期(事实上为什么一定会在1000000内出现还是没有证明)。
代码:
#include<iostream>#include<cmath>#include<vector>#include<cstdio>#include<cstring>#define N 1000000using namespace std;typedef long long inta;int fi[40];int prime[N+5];vector<int> primev;int fi_mod[N+5];void pre(){ fi[0]=1; fi[1]=1; for(int i=2;i<40;i++) { fi[i]=fi[i-1]+fi[i-2]; } prime[0]=1; prime[1]=1; for(int i=2;i<=1000;i++) if(prime[i]==0) for(int j=i*i;j<=N;j+=i) prime[j]=1; for(int i=2;i<N;i++) if(prime[i]==0) primev.push_back(i);}inta quick_mod(inta a,inta b,inta m){ inta ans=1; while(b) { if(b&1) ans=(ans*a)%m; a=(a*a)%m; b>>=1; } return ans;}inta fy(int m){ if(prime[m]==0) return m-1; int p_size=primev.size(); inta ans=m; for(int i=0;i<p_size;i++) { if(primev[i]>m) break; if(m%primev[i]==0) { ans/=primev[i]; ans*=(primev[i]-1); while(m%primev[i]==0) m/=primev[i]; } } return ans;}int main(){ pre(); inta a,b,n,p; int index=0; int cas; cin>>cas; while(cin>>a>>b>>p>>n) { printf("Case #%d: ",++index); if(n==1) { cout<<a%p<<endl; } else if(n==2) { cout<<b%p<<endl; } else if(n<=33) { inta aa=quick_mod(a,fi[n-3],p); inta bb=quick_mod(b,fi[n-2],p); cout<<aa*bb%p<<endl; } else { // 找到周期 int fyp=fy(p); fi_mod[0]=1; fi_mod[1]=1; int i; for(i=2;i<N;i++) { if(i>2&&fi_mod[i-1]==1&&fi_mod[i-2]==1) break; fi_mod[i]=(fi_mod[i-1]+fi_mod[i-2])%fyp; } int circle=i-2; inta aa=quick_mod(a,fi_mod[(n-3)%circle]+fyp,p); inta bb=quick_mod(b,fi_mod[(n-2)%circle]+fyp,p); cout<<(aa*bb)%p<<endl; } }}
实际上,用矩阵乘法算fibonacci数列会好很多啊 不必去想它的周期是否存在。
稍作修改 增加矩阵的快速幂
代码:
#include<iostream>#include<cmath>#include<vector>#include<cstdio>#include<cstring>#define N 1000000using namespace std;typedef long long inta;int fi[40];int prime[N+5];vector<int> primev;int fi_mod[N+5];void pre(){ fi[0]=1; fi[1]=1; for(int i=2;i<40;i++) { fi[i]=fi[i-1]+fi[i-2]; } prime[0]=1; prime[1]=1; for(int i=2;i<=1000;i++) if(prime[i]==0) for(int j=i*i;j<=N;j+=i) prime[j]=1; for(int i=2;i<N;i++) if(prime[i]==0) primev.push_back(i);}inta fy(int m){ if(prime[m]==0) return m-1; int p_size=primev.size(); inta ans=m; for(int i=0;i<p_size;i++) { if(primev[i]>m) break; if(m%primev[i]==0) { ans/=primev[i]; ans*=(primev[i]-1); while(m%primev[i]==0) m/=primev[i]; } } return ans;}inta quick_mod(inta a,inta b,inta m){ inta ans=1; while(b) { if(b&1) ans=(ans*a)%m; a=(a*a)%m; b>>=1; } return ans;}struct matrix{ inta m[2][2]; matrix() { m[0][0]=1; m[1][1]=1; m[1][0]=0; m[0][1]=0; };};matrix multi(matrix a,matrix b,int mod){ matrix ans; for(int i=0;i<2;i++) for(int j=0;j<2;j++) { ans.m[i][j]=(a.m[i][0]*b.m[0][j]+a.m[i][1]*b.m[1][j])%mod; } return ans;}matrix quick_mod(matrix a,int b,int mod ){ matrix ans; while(b) { if(b&1) ans=multi(ans,a,mod); a=multi(a,a,mod); b>>=1; } return ans;}int main(){ pre(); inta a,b,n,p; int index=0; int cas; cin>>cas; while(cin>>a>>b>>p>>n) { printf("Case #%d: ",++index); if(n==1) { cout<<a%p<<endl; } else if(n==2) { cout<<b%p<<endl; }// else if(n<=33)// {//// inta aa=quick_mod(a,fi[n-3],p);// inta bb=quick_mod(b,fi[n-2],p);// cout<<aa*bb%p<<endl;// } else { // 找到周期 int fyp=fy(p); matrix A; A.m[0][0]=1; A.m[0][1]=1; A.m[1][0]=1; A.m[1][1]=0; A=quick_mod(A,n-3,fyp); int fn_2=A.m[0][0]+A.m[1][0]; int fn_3=A.m[0][1]+A.m[1][1]; inta aa=quick_mod(a,fn_3,p); inta bb=quick_mod(b,fn_2,p); cout<<aa*bb%p<<endl; } }}
- hdu 3221 Brute-force Algorithm (09上海区域赛)欧拉定理
- Hdu 3221 Brute-force Algorithm (矩阵 欧拉定理降幂)
- HDU 3221 Brute-force Algorithm(欧拉公式降幂)
- hdu 3221 Brute-force Algorithm
- hdu 3221 Brute-force Algorithm
- hdu 3221 Brute-force Algorithm
- HDU 3221 Brute-force Algorithm
- HDU 3221 Brute-force Algorithm
- HDU 3221 Brute-force Algorithm
- HDU 3221Brute-force Algorithm
- HDU 3221 Brute-force Algorithm
- HDU3221-Brute—force Algorithm(欧拉函数)
- hdu 3221 Brute-force Algorithm 指数循环节
- HDU 3221Brute-force Algorithm(降幂公式 神似hdu4549)
- HDU 3221 Brute-force Algorithm(指数降幂公式)
- HDU 3221 Brute-force Algorithm(矩阵求fibnacci,指数取模)
- hdu 3221 Brute-force Algorithm(快速幂取模,矩阵快速幂求fib)
- 字符串匹配算法之Brute force algorithm
- java双缓冲技术
- Windows程序设计学习笔记--第一个Windows程序以及宽字符集(了解)
- 两个集合求差集
- 【leetcode】Remove Element
- python_网络编程
- hdu 3221 Brute-force Algorithm (09上海区域赛)欧拉定理
- ubuntu下搭载android开发环境发现新建工程里R文件报错
- 点击对话框以外的地方,对话框消失
- 【leetcode】Remove Duplicates from Sorted Array
- 计算100以内的素数的个数
- HDOJ 4389 —— 数位DP
- 云计算和大数据入门
- 9月10日美团网2014校招研发笔试哈尔滨站
- Windows Azure使用必读