BZOJ 1409 快速幂+欧拉定理
2017-07-30 18:36
197 查看
Description
Rivest是密码学专家。近日他正在研究一种数列E = {E[1],E[2],……,E }, 且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
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 3Sample Input
输入样例12 7
4 5
4 6
输入样例2
4 7
2 4
7 1
6 5
9 3
Sample Output
输出样例13
1
输出样例2
3
0
1
1
作为一个良心的人,我会粘题面的哈哈,因为防止BZOJ 炸掉没有办法看题面。。
又是考试题,比较水,手推一下E
的系数是斐波那契数列,但是没办法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\n",fast(p,tmp1+Mod,q)%q);
}
}
相关文章推荐
- BZOJ 1951 [Sdoi2010]古代猪文 欧拉定理+(扩展)lucas定理+逆元+快速幂
- bzoj 1409 Password 矩阵快速幂+欧拉函数
- bzoj 1409 Password 矩阵快速幂+欧拉函数
- [ 欧拉定理 矩阵快速幂 ] BZOJ5118
- bzoj 4036: [HAOI2015]按位或 快速莫比乌斯变换+期望dp
- 【BZOJ 2179】 FFT快速傅立叶|FFT
- 【bzoj3884】上帝与集合的正确用法 欧拉函数+欧拉定理
- [BZOJ2194]快速傅立叶之二
- 【BZOJ4869】相逢是问候(线段树,欧拉定理)
- bzoj2179 FFT快速傅立叶
- BZOJ 1898: [Zjoi2004]Swamp 沼泽鳄鱼( dp + 矩阵快速幂 )
- 【SDOI2011】【BZOJ】【P2242】【计算器】【题解】【快速幂+扩展欧几里得+高次同余方程/BSGS】
- [bzoj3884]上帝与集合的正确用法 欧拉定理
- 【BZOJ】2194: 快速傅立叶之二
- BZOJ 3992: [SDOI2015]序列统计 NTT+快速幂
- 【BZOJ 3884】上帝与集合的正确用法【欧拉定理】&【剧毒题】
- 【bzoj1706/usaco2007 Nov】relays 奶牛接力跑——矩阵快速幂/倍增floyd
- [bzoj 1009] [HNOI2008]GT考试:DP,单串AC自动机,矩阵快速幂
- BZOJ 2194 快速傅立叶之二
- BZOJ 2242: [SDOI2011]计算器( 快速幂 + 扩展欧几里德 + BSGS )