zoukankan      html  css  js  c++  java
  • bzoj 1409 Password

    题目大意:

    一种数列E = {E[1],E[2],……,E[n]}

    且E[1] = E[2] = p(p为一个质数),E[i] = E[i-2]*E[i-1] (若2<i<=n)

    在此基础上他又设计了一种加密算法,该算法可以通过一个密钥q (q < p)将一个正整数n加密成另外一个正整数d,计算公式为:d = E[n] mod q

    思路:

    首先可以想到快速幂

    然后就是求一个数的斐波那契n项次方

    因为斐波那契n项很大 所以log n很大会炸

    因为p^phi(q)%q=1,注意q不一定是质数

    所以只需要求出 f[i]%phi(q) 然后快速幂

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cmath>
     4 #include<cstdlib>
     5 #include<cstring>
     6 #include<algorithm>
     7 #include<vector>
     8 #include<queue>
     9 #define inf 2139062143
    10 #define ll long long
    11 #define MAXN 100100
    12 using namespace std;
    13 inline ll read()
    14 {
    15     ll x=0,f=1;char ch=getchar();
    16     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
    17     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
    18     return x*f;
    19 }
    20 ll p[MAXN],ntp[MAXN],cnt,n,m,mod,T,m1;
    21 struct mat {ll num[2][2];};  
    22 mat mul(mat x,mat y)  
    23 {  
    24     mat res;
    25     memset(res.num,0,sizeof(res.num));  
    26     for(ll i=0;i<2;i++)  
    27         for(ll j=0;j<2;j++)  
    28             for(ll k=0;k<2;k++)  
    29                 (res.num[i][j]+=x.num[i][k]*y.num[k][j])%=m1;
    30     return res;
    31 }
    32 ll mat_q_pow(ll n)
    33 {
    34     if(n<=0) return 0;
    35     mat t,res;
    36     memset(res.num,0,sizeof(res.num));
    37     t.num[0][0]=t.num[0][1]=t.num[1][0]=1,t.num[1][1]=0;
    38     res.num[0][0]=res.num[1][1]=1;
    39     while(n)
    40     {
    41         if(n&1) res=mul(res,t);
    42         t=mul(t,t);
    43         n>>=1;
    44     }
    45     return res.num[0][1];
    46 }
    47 void mem()
    48 {
    49     for(ll i=2;i<MAXN;i++)
    50     {
    51         if(!ntp[i]) p[++cnt]=i;
    52         for(ll j=1;p[j]*i<MAXN;j++)
    53         {
    54             ntp[p[j]*i]=1;
    55             if(i%p[j]==0) break;
    56         }
    57     }
    58 }
    59 void phi(ll x)
    60 {
    61     ll res=x;
    62     for(ll i=1;p[i]*p[i]<=x;i++)
    63         if(x%p[i]==0)
    64         {
    65             res/=p[i],res*=p[i]-1;
    66             while(x%p[i]==0) x/=p[i];
    67         }
    68     if(x!=1) res/=x,res*=x-1;
    69     m1=res;
    70 }
    71 ll num_q_pow(ll k,ll x)
    72 {
    73     ll res=1;
    74     while(x)
    75     {
    76         if(x&1) (res*=k)%=mod;
    77         (k*=k)%=mod,x>>=1;
    78     }
    79     return res;
    80 }
    81 int main()
    82 {
    83     T=read(),n=read();
    84     mem();
    85     while(T--)
    86     {
    87         m=read(),mod=read();
    88         phi(mod);
    89         printf("%lld
    ",num_q_pow(n,mat_q_pow(m))%mod);
    90     }
    91 }
    View Code
  • 相关阅读:
    生信入门-爱课程上的华中农业大学
    PAT 1115 Counting Nodes in a BST[构建BST]
    PAT 1133 Splitting A Linked List[链表][简单]
    PAT 1037 Magic Coupon[dp]
    PAT 1033 To Fill or Not to Fill[dp]
    畅通工程续 HDU1874
    Free DIY Tour HDU1224
    六度分离 HDU1869
    Arbitrage HDU1217
    floyed算法
  • 原文地址:https://www.cnblogs.com/yyc-jack-0920/p/8515960.html
Copyright © 2011-2022 走看看