poj 3243
Clever Y
Time Limit: 5000MS | Memory Limit: 65536K | |
Total Submissions: 6862 | Accepted: 1677 |
Description
Little Y finds there is a very interesting formula in mathematics:
XY mod Z = K
Given X, Y, Z, we all know how to figure out K fast. However, given X, Z, K, could you figure out Y fast?
Input
Input data consists of no more than 20 test cases. For each test case, there would be only one line containing 3 integers
X,
Z,
K (0 ≤
X,
Z,
K ≤ 10
9).
Input file ends with 3 zeros separated by spaces.
Input file ends with 3 zeros separated by spaces.
Output
For each test case output one line. Write "No Solution" (without quotes) if you cannot find a feasible
Y (0 ≤
Y <
Z). Otherwise output the minimum
Y you find.
Sample Input
5 58 33 2 4 3 0 0 0
Sample Output
9 No Solution
#include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <string.h>
#include <string>
#include <vector>
#include <queue>
#define MEM(a,x) memset(a,x,sizeof a)
#define eps 1e-8
#define MOD 10009
#define MAXN 65535
#define MAXM 100010
#define INF 99999999
#define ll __int64
#define bug cout<<"here"<<endl
#define fread freopen("ceshi.txt","r",stdin)
#define fwrite freopen("out.txt","w",stdout)
using namespace std;
int Read()
{
char ch;
int a = 0;
while((ch = getchar()) == ' ' | ch == '\n');
a += ch - '0';
while((ch = getchar()) != ' ' && ch != '\n')
{
a *= 10;
a += ch - '0';
}
return a;
}
void Print(int a) //输出外挂
{
if(a>9)
Print(a/10);
putchar(a%10+'0');
}
struct hash
{
int a,b,next;
}Hash[MAXN*2];
int flag[MAXN+66];
int top,index;
void ins(int a,int b)
{
int k=b&MAXN;
if(flag[k]!=index)
{
flag[k]=index;
Hash[k].next=-1;
Hash[k].a=a;
Hash[k].b=b;
return;
}
while(Hash[k].next!=-1)
{
if(Hash[k].b==b)
return;
k=Hash[k].next;
}
Hash[k].next=++top;
Hash[top].next=-1;
Hash[top].a=a;
Hash[top].b=b;
}
int find(int b)
{
int k=b&MAXN;
if(flag[k]!=index) return -1;
while(k!=-1)
{
if(Hash[k].b==b)
return Hash[k].a;
k=Hash[k].next;
}
return -1;
}
int gcd(int a,int b)
{
if(b==0) return a;
return gcd(b,a%b);
}
int Exgcd(int a,int b,int &x,int &y)
{
int t,ret;
if(!b)
{
x=1; y=0; return a;
}
ret=Exgcd(b,a%b,x,y);
t=x; x=y; y=t-a/b*y;
return ret;
}
int Inval(int a,int b,int n)
{
int x,y,e;
Exgcd(a,n,x,y);
e=(ll)x*b%n;
return e<0?e+n:e;
}
int pow_mod(ll a,int b,int c)
{
ll ret=1%c; a%=c;
while(b)
{
if(b&1)
ret=ret*a%c;
a=a*a%c;
b>>=1;
}
return ret;
}
int BabyStep(int A,int B,int C)
{
top=MAXN; ++index;
ll buf=1%C,D=buf,K;
int i,d=0,tmp;
for(i=0;i<=100;buf=buf*A%C,++i)
if(buf==B)
return i;
while((tmp=gcd(A,C))!=1)
{
if(B%tmp) return -1;
++d;
C/=tmp;
B/=tmp;
D=D*A/tmp%C;
}
int M=(int)ceil(sqrt((double)C));
for(buf=1%C,i=0;i<=M;buf=buf*A%C,++i)
ins(i,buf);
for(i=0,K=pow_mod((ll)A,M,C);i<=M;D=D*K%C,++i)
{
tmp=Inval((int)D,B,C);
int w;
if(tmp>=0&&(w=find(tmp))!=-1)
return i*M+w+d;
}
return -1;
}
int main()
{
//fread;
int A,B,C;
while(scanf("%d%d%d",&A,&C,&B)!=EOF)
{
if((A+B+C)==0) break;
B%=C;
int res=BabyStep(A,B,C);
if(res<0) puts("No Solution");
else printf("%d\n",res);
}
return 0;
}
poj 2417
Discrete Logging
Description
Given a prime P, 2 <= P < 2
31, an integer B, 2 <= B < P, and an integer N, 1 <= N < P, compute the discrete logarithm of N, base B, modulo P. That is, find an integer L such that
BL == N (mod P) Input
Read several lines of input, each containing P,B,N separated by a space.
Output
For each line print the logarithm on a separate line. If there are several, print the smallest; if there is none, print "no solution".
Sample Input 5 2 1 5 2 2 5 2 3 5 2 4 5 3 1 5 3 2 5 3 3 5 3 4 5 4 1 5 4 2 5 4 3 5 4 4 12345701 2 1111111 1111111121 65537 1111111111 Sample Output 0 1 3 2 0 3 1 2 0 no solution no solution 1 9584351 462803587 Hint
The solution to this problem requires a well known result in number theory that is probably expected of you for Putnam but not ACM competitions. It is Fermat's theorem that states
B(P-1) == 1 (mod P) for any prime P and some other (fairly rare) numbers known as base-B pseudoprimes. A rarer subset of the base-B pseudoprimes, known as Carmichael numbers, are pseudoprimes for every base between 2 and P-1. A corollary to Fermat's theorem is that for any m B(-m) == B(P-1-m) (mod P) . Source |
这题跟上题差不多。。
//#include <cstdio>
//#include <iostream>
//#include <cstring>
//#include <cmath>
//#include <algorithm>
//#include <string.h>
//#include <string>
//#include <vector>
//#include <queue>
//
//#define MEM(a,x) memset(a,x,sizeof a)
//#define eps 1e-8
//#define MOD 10009
//#define MAXN 65535
//#define MAXM 100010
//#define INF 99999999
//#define ll long long
//#define bug cout<<"here"<<endl
//#define fread freopen("ceshi.txt","r",stdin)
//#define fwrite freopen("out.txt","w",stdout)
//
//using namespace std;
//
//ll Read()
//{
// char ch;
// ll a = 0;
// while((ch = getchar()) == ' ' | ch == '\n');
// a += ch - '0';
// while((ch = getchar()) != ' ' && ch != '\n')
// {
// a *= 10;
// a += ch - '0';
// }
// return a;
//}
//
//void Prll(ll a) //输出外挂
//{
// if(a>9)
// Prll(a/10);
// putchar(a%10+'0');
//}
//
//struct hash
//{
// ll a,b,next;
//}Hash[MAXN*2];
//ll flag[MAXN+66];
//ll top,index;
//void ins(ll a,ll b)
//{
// ll k=b&MAXN;
// if(flag[k]!=index)
// {
// flag[k]=index;
// Hash[k].next=-1;
// Hash[k].a=a;
// Hash[k].b=b;
// return;
// }
// while(Hash[k].next!=-1)
// {
// if(Hash[k].b==b)
// return;
// k=Hash[k].next;
// }
// Hash[k].next=++top;
// Hash[top].next=-1;
// Hash[top].a=a;
// Hash[top].b=b;
//}
//ll find(ll b)
//{
// ll k=b&MAXN;
// if(flag[k]!=index) return -1;
// while(k!=-1)
// {
// if(Hash[k].b==b)
// return Hash[k].a;
// k=Hash[k].next;
// }
// return -1;
//}
//ll gcd(ll a,ll b)
//{
// if(b==0) return a;
// return gcd(b,a%b);
//}
//ll Exgcd(ll a,ll b,ll &x,ll &y)
//{
// ll t,ret;
// if(!b)
// {
// x=1; y=0; return a;
// }
// ret=Exgcd(b,a%b,x,y);
// t=x; x=y; y=t-a/b*y;
// return ret;
//}
//ll Inval(ll a,ll b,ll n)
//{
// ll x,y,e;
// Exgcd(a,n,x,y);
// e=(ll)x*b%n;
// return e<0?e+n:e;
//}
//ll pow_mod(ll a,ll b,ll c)
//{
// ll ret=1%c; a%=c;
// while(b)
// {
// if(b&1)
// ret=ret*a%c;
// a=a*a%c;
// b>>=1;
// }
// return ret;
//}
//ll BabyStep(ll A,ll B,ll C)
//{
// top=MAXN; ++index;
// ll buf=1%C,D=buf,K;
// ll i,d=0,tmp;
// for(i=0;i<=100;buf=buf*A%C,++i)
// if(buf==B)
// return i;
// while((tmp=gcd(A,C))!=1)
// {
// if(B%tmp) return -1;
// ++d;
// C/=tmp;
// B/=tmp;
// D=D*A/tmp%C;
// }
// ll M=(ll)ceil(sqrt((double)C));
// for(buf=1%C,i=0;i<=M;buf=buf*A%C,++i)
// ins(i,buf);
// for(i=0,K=pow_mod((ll)A,M,C);i<=M;D=D*K%C,++i)
// {
// tmp=Inval((ll)D,B,C);
// ll w;
// if(tmp>=0&&(w=find(tmp))!=-1)
// return i*M+w+d;
// }
// return -1;
//}
//
//int main()
//{
//// fread;
// ll A,B,C;
// while(scanf("%lld%lld%lld",&C,&A,&B)!=EOF)
// {
// B%=C;
// ll res=BabyStep(A,B,C);
// if(res<0) puts("no solution");
// else printf("%lld\n",res);
// }
// return 0;
//}
//
#include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <string.h>
#include <string>
#include <vector>
#include <queue>
#define MEM(a,x) memset(a,x,sizeof a)
#define eps 1e-8
#define MOD 10009
#define MAXN 65535
#define MAXM 100010
#define INF 99999999
#define ll long long
#define bug cout<<"here"<<endl
#define fread freopen("ceshi.txt","r",stdin)
#define fwrite freopen("out.txt","w",stdout)
using namespace std;
int Read()
{
char ch;
int a = 0;
while((ch = getchar()) == ' ' | ch == '\n');
a += ch - '0';
while((ch = getchar()) != ' ' && ch != '\n')
{
a *= 10;
a += ch - '0';
}
return a;
}
void Print(int a) //输出外挂
{
if(a>9)
Print(a/10);
putchar(a%10+'0');
}
struct hash
{
int a,b,next;
}Hash[MAXN*2];
int flag[MAXN+66];
int top,index;
void ins(int a,int b)
{
int k=b&MAXN;
if(flag[k]!=index)
{
flag[k]=index;
Hash[k].next=-1;
Hash[k].a=a;
Hash[k].b=b;
return;
}
while(Hash[k].next!=-1)
{
if(Hash[k].b==b)
return;
k=Hash[k].next;
}
Hash[k].next=++top;
Hash[top].next=-1;
Hash[top].a=a;
Hash[top].b=b;
}
int find(int b)
{
int k=b&MAXN;
if(flag[k]!=index) return -1;
while(k!=-1)
{
if(Hash[k].b==b)
return Hash[k].a;
k=Hash[k].next;
}
return -1;
}
int gcd(int a,int b)
{
if(b==0) return a;
return gcd(b,a%b);
}
int Exgcd(int a,int b,int &x,int &y)
{
int t,ret;
if(!b)
{
x=1; y=0; return a;
}
ret=Exgcd(b,a%b,x,y);
t=x; x=y; y=t-a/b*y;
return ret;
}
int Inval(int a,int b,int n)
{
int x,y,e;
Exgcd(a,n,x,y);
e=(ll)x*b%n;
return e<0?e+n:e;
}
int pow_mod(ll a,int b,int c)
{
ll ret=1%c; a%=c;
while(b)
{
if(b&1)
ret=ret*a%c;
a=a*a%c;
b>>=1;
}
return ret;
}
int BabyStep(int A,int B,int C)
{
top=MAXN; ++index;
ll buf=1%C,D=buf,K;
int i,d=0,tmp;
for(i=0;i<=100;buf=buf*A%C,++i)
if(buf==B)
return i;
while((tmp=gcd(A,C))!=1)
{
if(B%tmp) return -1;
++d;
C/=tmp;
B/=tmp;
D=D*A/tmp%C;
}
int M=(int)ceil(sqrt((double)C));
for(buf=1%C,i=0;i<=M;buf=buf*A%C,++i)
ins(i,buf);
for(i=0,K=pow_mod((ll)A,M,C);i<=M;D=D*K%C,++i)
{
tmp=Inval((int)D,B,C);
int w;
if(tmp>=0&&(w=find(tmp))!=-1)
return i*M+w+d;
}
return -1;
}
int main()
{
// fread;
int A,B,C;
while(scanf("%d%d%d",&C,&A,&B)!=EOF)
{
B%=C;
int res=BabyStep(A,B,C);
if(res<0) puts("no solution");
else printf("%d\n",res);
}
return 0;
}