2480: Spoj3105 Mod
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 557 Solved: 210
[Submit][Status][Discuss]
Description
已知数a,p,b,求满足a^x≡b(mod p)的最小自然数x。
Input
每个测试文件中最多包含100组测试数据。
每组数据中,每行包含3个正整数a,p,b。
当a=p=b=0时,表示测试数据读入完全。
Output
对于每组数据,输出一行。
如果无解,输出“No Solution”(不含引号),否则输出最小自然数解。
Sample Input
5 58 33
2 4 3
0 0 0
2 4 3
0 0 0
Sample Output
9
No Solution
No Solution
【吐槽】
一道很简单的模板题。
当p=1时记得要特判。。。(博主因为这个wa了无数次)
1 /************* 2 bzoj 2480 3 by chty 4 2016.11.8 5 *************/ 6 #include<iostream> 7 #include<cstdio> 8 #include<cstring> 9 #include<cstdlib> 10 #include<ctime> 11 #include<cmath> 12 #include<algorithm> 13 using namespace std; 14 #define mod 99991 15 typedef long long ll; 16 struct node{ll v,num,f;}hash[mod+10]; 17 ll A,B,C; 18 inline ll read() 19 { 20 ll x=0,f=1; char ch=getchar(); 21 while(!isdigit(ch)) {if(ch=='-') f=-1; ch=getchar();} 22 while(isdigit(ch)) {x=x*10+ch-'0'; ch=getchar();} 23 return x*f; 24 } 25 ll gcd(ll a,ll b) {return !b?a:gcd(b,a%b);} 26 void insert(ll v,ll x) 27 { 28 ll t=v%mod; 29 while(hash[t].f&&hash[t].v!=v) {t++; if(t>mod) t-=mod;} 30 if(!hash[t].f) {hash[t].f=1;hash[t].num=x;hash[t].v=v;} 31 } 32 ll find(ll v) 33 { 34 ll t=v%mod; 35 while(hash[t].f&&hash[t].v!=v) {t++; if(t>mod) t-=mod;} 36 if(!hash[t].f) return -1; 37 else return hash[t].num; 38 } 39 void exgcd(ll a,ll b,ll &x,ll &y) 40 { 41 if(!b) {x=1; y=0; return;} 42 exgcd(b,a%b,x,y); 43 ll t=x;x=y;y=t-a/b*y; 44 } 45 ll Shank() 46 { 47 ll ret=1; 48 for(ll i=0;i<=50;i++) {if(ret==B) return i;ret=ret*A%C;} 49 ll temp,ans(1),cnt(0); 50 while((temp=gcd(A,C))!=1) 51 { 52 if(B%temp) return -1; 53 C/=temp; B/=temp; 54 ans=ans*(A/temp)%C; 55 cnt++; 56 } 57 ll m=(ll)ceil(sqrt(C*1.0)),t(1); 58 for(ll i=0;i<m;i++) {insert(t,i);t=t*A%C;} 59 for(ll i=0;i<m;i++) 60 { 61 ll x,y; 62 exgcd(ans,C,x,y); 63 ll val=x*B%C; 64 val=(val%C+C)%C; 65 ll j=find(val); 66 if(j!=-1) return m*i+j+cnt; 67 ans=ans*t%C; 68 } 69 return -1; 70 } 71 void pre() {for(int i=0;i<=mod;i++)hash[i].f=0,hash[i].num=hash[i].v=-1;} 72 int main() 73 { 74 freopen("cin.in","r",stdin); 75 freopen("cout.out","w",stdout); 76 while(~scanf("%d%d%d",&A,&C,&B)) 77 { 78 if(!(A+B+C)) break; 79 if(C==1) {puts("0"); continue;} 80 pre(); A%=C; B%=C; 81 ll ans=Shank(); 82 if(ans==-1) puts("No Solution"); 83 else printf("%lld ",ans); 84 } 85 return 0; 86 }