zoukankan      html  css  js  c++  java
  • ZOJ 3707 Calculate Prime S 数论

    思路:容易得到s[n]=s[n-1]+s[n-2],也就是fib数。

    求第k小的fib质数的也就是第k个质数数-2,当k>2时。

    在就是s[n]/x%m=s[n]%(x*m)/x.

    代码如下:

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #define ll long long
    #define M 1000005
    using namespace std;
    ll k,x,m;
    int prime[M],cnt;
    bool f[20*M];
    struct mat
    {
        ll m[2][2];
    };
    mat mul(mat a,mat b,ll mod)
    {
        mat ans;
        for(int i=0;i<2;i++)
        for(int j=0;j<2;j++){
            ans.m[i][j]=0;
            for(int z=0;z<2;z++)
                ans.m[i][j]=(ans.m[i][j]+a.m[i][z]*b.m[z][j])%mod;
        }
        return ans;
    }
    ll pw(ll n,ll mod)
    {
        mat ans,a;
        for(int i=0;i<2;i++)
        for(int j=0;j<2;j++){
            ans.m[i][j]=0;
            a.m[i][j]=1;
        }
        ans.m[0][0]=2;ans.m[0][1]=1;a.m[1][1]=0;
        while(n){
            if(n&1) ans=mul(ans,a,mod);
            n>>=1;
            a=mul(a,a,mod);
        }
        ll aa=ans.m[0][1];
        ll bb=ans.m[0][0];
        while(1){
            if(bb%x==0) break;
            ll t=(aa+bb)%mod;
            aa=bb;
            bb=t;
        }
        return bb;
    }
    void init()
    {
        cnt=1;
        for(int i=2;i<20*M;i++){
            if(cnt>=1000001) break;
            if(!f[i]) prime[cnt++]=i;
            for(int j=1;j<cnt&&i*prime[j]<20*M;j++){
                f[i*prime[j]]=1;
                if(i%prime[j]==0) break;
            }
        }
    }
    ll gcd(ll a,ll b)
    {
        if(a<b) swap(a,b);
        while(b){
            ll t=a;
            a=b;
            b=t%b;
        }
        return a;
    }
    ll cal(ll mod)
    {
        ll a=2,b=3,c;
        if(k==1) c=2;
        else c=3;
        while(1){
            if(a>=c&&a%x==0) break;
            ll t=(a+b)%mod;
            a=b;
            b=t;
        }
        return a;
    }
    int main()
    {
        int t;
        init();
        scanf("%d",&t);
        while(t--){
            scanf("%lld%lld%lld",&k,&x,&m);
            ll ans,g=x*m;
            if(k<=2) ans=cal(g);
            else ans=pw(prime[k]-2,g);
            printf("%lld
    ",ans/x);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    (转)CSS3之pointer-events(屏蔽鼠标事件)属性说明
    Linux下source命令详解
    控制台操作mysql常用命令
    解决beego中同时开启http和https时,https端口占用问题
    有关亚马逊云的使用链接收集
    favicon.ico--网站标题小图片二三事
    网络博客
    Gitbook 命令行工具
    Markdown 轻量级标记语言
    SVN 集中式版本控制系统
  • 原文地址:https://www.cnblogs.com/xin-hua/p/3400164.html
Copyright © 2011-2022 走看看