zoukankan      html  css  js  c++  java
  • BZOJ 1409 快速幂+欧拉定理

    Description

    Rivest是密码学专家。近日他正在研究一种数列E = {E[1],E[2],……,E[n]},
    且E[1] = E[2] = p(p为一个质数),E[i] = E[i-2]*E[i-1] (若2<i<=n)。
    
    例如{2,2,4,8,32,256,8192,……}就是p = 2的数列。在此基础上他又设计了一种加密算法,该算法可以通过一个密钥q (q < p)将一个正整数n加密成另外一个正整数d,计算公式为:d = E[n] mod q。现在Rivest想对一组数据进行加密,但他对程序设计不太感兴趣,请你帮助他设计一个数据加密程序。

    Input

    第一行读入m,p。其中m表示数据个数,p用来生成数列E。 以下有m行,每行有2个整数n,q。n为待加密数据,q为密钥。 数据范围: 0 < p n< 2^31 0 < q < p 0 < m <= 5000。

    Output

    将加密后的数据按顺序输出到文件 第i行输出第i个加密后的数据。 输入样例1 2 7 4 5 4 6 输入样例2 4 7 2 4 7 1 6 5 9 3

    Sample Input

    输入样例1
    2 7
    4 5
    4 6
    输入样例2
    4 7
    2 4
    7 1
    6 5
    9 3

    Sample Output

    输出样例1
    3
    1

    输出样例2
    3
    0
    1
    1
    作为一个良心的人,我会粘题面的哈哈,因为防止BZOJ 炸掉没有办法看题面。。

    又是考试题,比较水,手推一下E[n]的系数是斐波那契数列,但是没办法mod,然后因为p,q互素,那么用欧拉定理就好了,用矩阵乘优化,模数为phi(q),然后再普通快速幂就好了,此题爆int。

    #include <stdio.h>
    #include <cstring>
    #include <cmath>
    using namespace std;
    typedef long long ll;
    const int MAXN = 60000;
    ll m,p,q,n,Mod,cnt;
    int prime[MAXN+5];
    bool _prime[MAXN+5];
     
     
    template<typename _t>
    inline _t read(){
        _t x=0,f=1;
        char ch=getchar();
        for(;ch>'9'||ch<'0';ch=getchar())if(ch=='-')f=-f;
        for(;ch>='0'&&ch<='9';ch=getchar())x=x*10+(ch^48);
        return x*f;
    }
     
    void get_prime(){
        for(int i=2;i<=MAXN;i++){
            if(!_prime[i])prime[++cnt]=i;
            for(int j=1;j<=cnt&&i*prime[j]<=MAXN;j++){
                _prime[i*prime[j]]=1;
                if(i%prime[j]==0)break;
            }
        }
    }
     
    inline ll fast(ll p,ll n,ll q){
        ll ans = 1;
        for(;n;n>>=1,p=p*p%q)
            if(n&1)
                ans=ans*p%q;
        return ans;
    }
     
    ll get_phi(ll x){
        if(x==1)return 1;
        ll ans=1;
        for(int i=1;prime[i]*prime[i]<=x;i++){
            if(x%prime[i]==0){
                ans *= prime[i]-1;
                x/=prime[i];
            }
            while(x%prime[i]==0){
                ans*=prime[i];
                x/=prime[i];
            }
        }
        if(x!=1)ans*=x-1;
        return ans;
    }
     
    struct matrix{
        ll a[5][5];
        matrix(){
            memset(a,0,sizeof a);
        }
    };
     
    inline matrix operator * (matrix a,matrix b){
        matrix ans;
        for(int i=1;i<=2;i++)
            for(int j=1;j<=2;j++)
                for(int k=1;k<=2;k++)
                    ans.a[i][j]=(ans.a[i][j]+a.a[i][k]*b.a[k][j]%Mod)%Mod;
        return ans;
    }
     
    inline matrix operator ^ (matrix a,ll k){
        matrix ans;
        for(int i=1;i<=2;i++)ans.a[i][i]=1;
        for(;k;k>>=1,a=a*a)
            if(k&1)
                ans=ans*a;
        return ans;
    }
     
    int main(){
        get_prime();
        m=read<ll>();
        p=read<ll>();
        while(m--){
            n=read<ll>();
            q=read<ll>();
            Mod = get_phi(q);
            matrix tmp;
            tmp.a[1][1]=tmp.a[1][2]=tmp.a[2][1]=1;
            if(n>1)
                tmp = tmp ^ (n-1);
            matrix Ans;
            Ans.a[1][1]=1;
            Ans = Ans*tmp;
            ll tmp1 = Ans.a[1][1];
            printf("%lld
    ",fast(p,tmp1+Mod,q)%q);
        }
    }




  • 相关阅读:
    信息安全系统设计基础实验五:通讯协议设计 20135211李行之 20135216刘蔚然
    信息安全系统设计基础实验四:外设驱动程序设计 20135211李行之&20135216刘蔚然
    信息安全系统设计基础第十二周学习总结
    实验三-实时系统的移植 20135211李行之 20135216刘蔚然
    实验二-固件设计 20135211李行之 20135216刘蔚然
    信息安全系统设计基础第十一周学习总结
    信息安全系统设计基础实验一 20135211&20135216
    信息安全设计基础第十周学习总结
    Oracle如何创建表空间、用户及授权
    设置nginx支持虚拟机,支持多域名多网站
  • 原文地址:https://www.cnblogs.com/Cooook/p/7738501.html
Copyright © 2011-2022 走看看