Description
原始问题:给出 A , B , X , N A,B,X,N A,B,X,N和一个素数 P P P,令 f ( X ) = A X + B f(X)=AX+B f(X)=AX+B,计算 f N ( X ) m o d P f^N(X)\ mod\ P fN(X) mod P
逆问题:给出 X , N , T X,N,T X,N,T和一个素数 P P P,找非负整数 A , B A,B A,B使得 1 ≤ A ≤ p − 1 , 0 ≤ B ≤ p − 1 1\le A\le p-1,0\le B\le p-1 1≤A≤p−1,0≤B≤p−1使得 f ( X ) N m o d P = T f(X)^N\ mod\ P=T f(X)N mod P=T
逆问题的逆问题:给出一整数 M M M,找 X , N , T , P X,N,T,P X,N,T,P满足 1 ≤ X ≤ 1 0 9 , 1 ≤ N ≤ 1 0 18 , 0 ≤ T < P ≤ M 1\le X\le 10^9,1\le N\le 10^{18},0\le T<P\le M 1≤X≤109,1≤N≤1018,0≤T<P≤M且 g ( X , N , T , P ) g(X,N,T,P) g(X,N,T,P)最大,其中 g ( X , N , T , P ) g(X,N,T,P) g(X,N,T,P)为 A A A的最小值使得其满足:存在 B B B使得 1 ≤ A ≤ p − 1 , 0 ≤ B ≤ p − 1 1\le A\le p-1,0\le B\le p-1 1≤A≤p−1,0≤B≤p−1使得 f ( X ) N m o d P = T f(X)^N\ mod\ P=T f(X)N mod P=T,如果无解则 g ( X , N , T , P ) = − 1 g(X,N,T,P)=-1 g(X,N,T,P)=−1.
Input
一个整数 M ( 3 ≤ M ≤ 1 0 5 ) M(3\le M\le 10^5) M(3≤M≤105)
Output
输出四个整数 X , N , T , P X,N,T,P X,N,T,P
Sample Input
8
Sample Output
2018 231 1 7
Solution
首先考虑已知 A , B , X , P , N A,B,X,P,N A,B,X,P,N时 T T T的值,由矩阵快速幂可知 T = f N ( X ) = ( A N X + ( 1 + A + . . . + A N − 1 ) B ) % P T=f^N(X)=(A^NX+(1+A+...+A^{N-1})B)\% P T=fN(X)=(ANX+(1+A+...+AN−1)B)%P
假设 A > 1 A>1 A>1,此时即判断 T − A N X ≡ A N − 1 A − 1 B m o d P T-A^NX\equiv \frac{A^N-1}{A-1}B\ mod\ P T−ANX≡A−1AN−1B mod P是否有解,不妨令 T = 1 , X = P T=1,X=P T=1,X=P,那么只要 A N − 1 ̸ ≡ 0 m o d P A^N-1\not \equiv 0\ mod\ P AN−1̸≡0 mod P则 B B B有解,显然可以取 A = 2 , N = 5 , P = 3 A=2,N=5,P=3 A=2,N=5,P=3使得该同余不等式成立,故该方程一定有 A > 1 A>1 A>1的解
为使 A A A最大,我们有 x N ≡ 1 m o d P , 2 ≤ x < A x^N\equiv 1\ mod\ P,2\le x<A xN≡1 mod P,2≤x<A且 A N ̸ ≡ 1 m o d P A^N\not\equiv 1\ mod\ P AN̸≡1 mod P,满足前一个条件只需取 N = l c m ( r ( 2 ) , . . . , r ( A − 1 ) ) N=lcm(r(2),...,r(A-1)) N=lcm(r(2),...,r(A−1))即可,其中 r ( x ) r(x) r(x)为使得 x g ≡ 1 m o d P x^g\equiv 1\ mod\ P xg≡1 mod P的最小正整数 g g g,满足第二个条件只需让 ( P − 1 ) ̸ ∣ N (P-1)\not|N (P−1)̸∣N即可,故直接枚举 P P P和 A A A即可,注意若 N < P N<P N<P把 N N N乘上 P P P即可,因为 ( P , P − 1 ) = 1 (P,P-1)=1 (P,P−1)=1
Code
#include<cstdio>
#include<algorithm>
#include<vector>
using namespace std;
typedef long long ll;
#define maxn 100005
vector<int>f[maxn],prime;
bool mark[maxn];
void init(int n=1e5)
{
for(int i=2;i<=n;i++)
if(!mark[i])
{
prime.push_back(i);
for(int j=2*i;j<=n;j+=i)mark[j]=1;
}
for(int i=1;i<=n;i++)
for(int j=i;j<=n;j+=i)
f[j].push_back(i);
}
int mul(int a,int b,int c)
{
ll z=1ll*a*b;
return z-z/c*c;
}
int Pow(int a,int b,int c)
{
int ans=1;
while(b)
{
if(b&1)ans=mul(ans,a,c);
a=mul(a,a,c);
b>>=1;
}
return ans;
}
ll gcd(ll a,ll b)
{
return b?gcd(b,a%b):a;
}
ll lcm(ll a,ll b)
{
return a/gcd(a,b)*b;
}
ll res[maxn];
int main()
{
init();
int m;
scanf("%d",&m);
int ma=0,ansp;
for(int i=0;i<prime.size()&&prime[i]<=m;i++)
{
int p=prime[i];
ll lc=1;
res[p]=lc;
for(int r=2;r<p;r++)
{
int ans=p-1;
for(int j=0;j<f[p-1].size();j++)
if(Pow(r,f[p-1][j],p)==1)
{
ans=f[p-1][j];
break;
}
lc=lcm(lc,ans);
if(lc%(p-1)==0)
{
if(r>ma)ma=r,ansp=p;
break;
}
else res[p]=lc;
}
}
if(res[ansp]<ansp)res[ansp]*=ansp;
printf("%d %lld 1 %d\n",ansp,res[ansp],ansp);
return 0;
}