Zoj 3707 calculate prime s

来源:互联网 发布:电信网络接入点那个快 编辑:程序博客网 时间:2024/04/28 09:34

题意:

  S[i]为1到 i 的自然数序列中不存在连续元素的子集的个数。S[n]与所有S[i](i<n)互质,则为Prime S。求(S[n]/X%M;

思路:

  集合性质:一个含n个元素的集合的子集数为2的n次方。由集合性质推得S[i+1]=S[i]+S[i-1],S[i]是斐波那契数。

 打表结果:

              S[1]=2,  S[2]=3, S[3]=5,  S[4]=8, S[5]=13,S[6]=21......

 fib[1]=1,fib[2]=1,fib[3]=2,fib[4]=3,fib[5]=5,fib[6]=8,fib[7]=13......

 从斐波那契数列的第五项(fib[4]为Prime S开始,每项斐波那契为Prime S(Prime S表示S[n]与所有S[i]互质)的条件为当且仅当它的项数为质数,因此采用素数打表的方法得到第kPrime S的斐波那契数的项数。然后用矩阵乘法求出第kS的值对应的下一个斐波那契数,然后枚举该斐波那契数,直到能被X整除。

#include <stdio.h>  #include <iostream>  #include <string.h>  #include <math.h>    using namespace std;  typedef long long LL;  const LL N=16000000;  LL p[N];  bool prime[N];  LL k=1;    void isprime()  //素数打表{      LL i,j;      p[0]=1;      memset(prime,true,sizeof(prime));      for(i=2;i<N;i++)      {          if(prime[i])          {              p[k++]=i;  //p数组保存素数            for(j=i+i;j<N;j+=i)              {                  prime[j]=false;              }          }      }      p[1]=3;p[2]=4;  }    typedef struct  {      LL m[2][2];  }Matrix;  Matrix per={1,0,0,1};  Matrix a={1,1,1,0};  Matrix multi(Matrix a,Matrix b,LL MOD)  //使用矩阵乘法求斐波那契数{      Matrix c;      LL i,j;      for(i=0;i<2;i++)      {          for(j=0;j<2;j++)          {              c.m[i][j]=0;              for(k=0;k<2;k++)              {                  c.m[i][j]+=a.m[i][k]*b.m[k][j];                  c.m[i][j]%=MOD;              }          }      }      return c;  }    Matrix matrix_mod(LL k,LL MOD)  //第k个斐波那契数取模{      Matrix p=a,ans=per;      while(k)      {          if(k&1)          {              ans=multi(ans,p,MOD);              k--;          }          k>>=1;          p=multi(p,p,MOD);      }      return ans;  }    int main()  {      LL K,X,M,t,i,ret,r;      isprime();      scanf("%lld",&t);      while(t--)      {          scanf("%lld%lld%lld",&K,&X,&M);          Matrix ans;            for(i=p[K];;i++)  //枚举斐波那契数S[n]        {              ans=matrix_mod(i-1,X);              if((ans.m[0][0]%X==0))//直至能整除              {                  r=i;                  break;              }          }          ans=matrix_mod(i-1,M*X); //斐波那契性质        ret=ans.m[0][0]/X;          printf("%lld\n",ret);      }      return 0;  }  


0 0
原创粉丝点击