【斐波拉契+数论+同余】【ZOJ3707】Calculate Prime S
来源:互联网 发布:生命密码测试软件 编辑:程序博客网 时间:2024/05/11 02:40
题目大意:
S[n] 表示 集合{1,2,3,4,5.......n} 不存在连续元素的子集个数
Prime S 表示S[n]与之前的所有S[i]互质;
问 找到大于第K个PrimeS 能整除X 的第一个S[n]
并且 输出(S[n]/X)%M
1.斐波拉契阶段
很容易写出S[n]的各个值发现是斐波拉契数列
2 3 5 8 13 21 34
2.斐波拉契性质
gcd(fib(n),fib(m))=fib(gcd(n,m)) (从1开始计算的即 1 1 2 3 5 8序列)
所以只有当 gcd(n,m)=1或2时 fib[n]与fib[m]互质
S[n]=fib[n+2]
所以若S[n] 要是一个 PrimeS
则n+2必须是一个质数或者4 ,自己画画就知道为什么4是特殊的了
所以构造一个特殊的素数表
P[i] 3 4 5 7 11 13...................
所以第K个PrimeS 就是fib[P[k]]
3.如何寻找整除X的数
从 fib[P[k]开始一个一个找 使得fib[P[k]]%X==0 的数即可
记录ansi=i;
4.同余公式的引用
(a/b)%c=(a%(b*c))/b
根据ansi 计算即可
代码如下:
/* TLE 1次 没注意1000000个质数 maxn 至少要1600W*/#include <cstdio>#include <cstdlib>#include <cstring>#include <ctime>#include <algorithm>#include <iostream>#include <sstream>#include <string>#define oo 0x13131313#define LL long longusing namespace std;const int maxn=16000001;int K,X,M;int p[2000001],tot=0;bool yn[maxn];struct node{ LL mat[3][3];};node matmult(node a,node b,int mod){ node c; memset(c.mat,0,sizeof(c.mat)); for(int i=1;i<=2;i++) for(int j=1;j<=2;j++) for(int k=1;k<=2;k++) c.mat[i][j]=(c.mat[i][j]+a.mat[i][k]*b.mat[k][j])%mod; return c;}node quickmatpow(node a,int n,int mod){ node c; memset(c.mat,0,sizeof(c.mat)); c.mat[1][1]=1;c.mat[1][2]=0;c.mat[2][1]=0;c.mat[2][2]=1; while(n!=0) { if(n&1==1) c=matmult(c,a,mod); a=matmult(a,a,mod); n=n>>1; } return c;}void get_prime(){ for(int i=2;i<maxn;i++) { if(yn[i]==false) { p[++tot]=i; for(int j=i;j<maxn;j=j+i) yn[j]=true; } } // printf("%d\n",tot); p[1]=3; p[2]=4;}void init(){ freopen("a.in","r",stdin); freopen("a.out","w",stdout);}int main(){ // init(); get_prime();int T;cin>>T;while(T--) { int ansi; int temp; node a,c; memset(a.mat,0,sizeof(a.mat)); memset(c.mat,0,sizeof(c.mat)); a.mat[1][1]=1,a.mat[1][2]=1,a.mat[2][1]=1,a.mat[2][2]=0; scanf("%d%d%d",&K,&X,&M); for(int i=p[K];;i++) { c=quickmatpow(a,i-2,X); temp=((c.mat[1][1]+c.mat[1][2]))%X; if(temp==0) { ansi=i; break; } } c=quickmatpow(a,ansi-2,M*X); temp=((c.mat[1][1]+c.mat[1][2]))%(M*X); printf("%d\n",temp/X); } return 0;}
0 0
- 【斐波拉契+数论+同余】【ZOJ3707】Calculate Prime S
- zoj3707 Calculate Prime S
- ZOJ3707 Calculate Prime S 数论好题目啊
- 同余(数论基础)
- 数论之同余
- 同余定理【数论】
- 数论-同余
- Zoj 3707 calculate prime s
- zoj 3707 Calculate Prime S
- ZOJ 3707Calculate Prime S
- 数论(同余+hash)
- 数论——同余
- 【算法】数论---同余定理
- poj2115 数论 同余方程
- 数论的同余定理
- 数论——同余
- 数论:从同余的观点出发
- 弃九法,数论同余学习笔记
- ACM之填写乘法算式
- 【基础】常用的机器学习&数据挖掘知识点
- android api
- //cosf 余弦 正弦 2M_PI / _cellCount 每一个的角度
- 分布式与集群的区别
- 【斐波拉契+数论+同余】【ZOJ3707】Calculate Prime S
- 基类与接口类中的虚析构函数(virtual destructor)
- 题目:去掉最大值、最小值后剩下的个数
- Java调用Zebra条码打印机打印条码、中英文数字条码混合标签,可自由控制格式和排版
- 拷贝构造函数和赋值表达式的区别
- C#自定义类中操作主窗体控件,通过委托实现
- 二维数组指针
- 带百度地图apk 签名打包后 地图key验证失败
- java邮件发送