BEST SOLVER
时间限制: 1 Sec 内存限制: 128 MB
提交: 33 解决: 16
[提交] [状态] [讨论版] [命题人:admin]
题目描述
The so-called best problem solver can easily solve this problem, with his/her childhood sweetheart.
It is known that For a given integer x (0 ≤ x < 232 ) and a given prime number M (M ≤ 46337), print [y]%M. ([y] means the integer part of y)
输入
An integer T (1 < T ≤ 1000), indicating there are T test cases. Following are T lines, each containing two integers x and M, as introduced above.
输出
The output contains exactly T lines. Each line contains an integer representing [y]%M.
样例输入
7 0 46337 1 46337 3 46337 1 46337 21 46337 321 46337 4321 46337
样例输出
Case #1: 97 Case #2: 969 Case #3: 16537 Case #4: 969 Case #5: 40453 Case #6: 10211 Case #7: 17947
来源/分类
解题思路:这一题于hdu4565很像,不同的是这个的幂很大,如果很小的话就很好求了,很大的话我就不会了。。
参考博客:https://blog.csdn.net/u012015746/article/details/52160247
根据欧拉准则和二次剩余定理我们可以找到该式的循环节。。
循环节可能位P-1 或者位 p*p-1 ,具体怎么证明的还不是很明白。
#include<bits/stdc++.h>
#define rep(i,j,k) for(int i=j;i<=k;i++)
#define sca(x) scanf("%d",&x);
#define LL long long
using namespace std;
LL mod;
struct node
{
LL a[3][3];
};
node mul(node x,node y)
{
node tmp;
memset(tmp.a,0,sizeof(tmp.a));
for(int i=1;i<=2;i++)
{
for(int j=1;j<=2;j++)
{
for(int k=1;k<=2;k++)
{
tmp.a[i][j]+=(x.a[i][k]*y.a[k][j])%mod;
}
tmp.a[i][j]%=mod;
}
}
//Print(tmp);
return tmp;
}
void solve(int k)
{
node ans,tmp;
memset(ans.a,0,sizeof(ans.a));
memset(tmp.a,0,sizeof(tmp.a));
ans.a[1][1]=5;ans.a[2][1]=2;
tmp.a[1][1]=5,tmp.a[1][2]=12;
tmp.a[2][1]=2,tmp.a[2][2]=5;
while(k)
{
if(k&1)
ans=mul(tmp,ans);
tmp=mul(tmp,tmp);
k>>=1;
}
printf("%d\n",(2*ans.a[1][1]-1)%mod);
}
LL qpow(LL a,LL k,LL m)
{
LL tmp=1;
m=m*m-1;
while(k)
{
if(k&1)
tmp=(tmp*a)%m;
a=(a*a)%m;
k>>=1;
}
return tmp;
}
int main()
{
int t;
cin>>t;
int cas=0;
while(t--)
{
int x;
scanf("%d%lld",&x,&mod);
printf("Case #%d: ",++cas);
LL tmp=qpow(2,x,mod);
solve(tmp);
}
}