NOIP 2012 同余方程

描述

求关于x的同余方程ax ≡ 1 (mod b)的最小正整数解。

格式

输入格式

输入只有一行,包含两个正整数a, b,用一个空格隔开。

输出格式

输出只有一行,包含一个正整数x0,即最小正整数解。输入数据保证一定有解。

样例1

样例输入1[复制]

 
3 10

样例输出1[复制]

 
7

限制

每个测试点1s

提示

对于40%的数据,2 ≤b≤ 1,000; 
对于60%的数据,2 ≤b≤ 50,000,000; 
对于100%的数据,2 ≤a, b≤ 2,000,000,000。

来源

Noip2012提高组复赛Day2T1

  分析:

  ax ≡ 1 (mod b) ,可以理解为 ax%b==1%b 因为1%b一定等于1,所以ax%b==1 ,有两种情况:

  1. ax==1 当a!=1时x不为整数,特判一下就好了(这两天写题给我的一个经验就是,一定要考虑特殊情况,多搞点特判一定没错,比如昨天写的“过河”,S==T的时候特判了,还能给30分的TLE算法多赚10分)

  2.ax-1==by ,x,y均为整数,移项可得:ax-by==1,由于y的正负不定所以可以最终化为ax+by==1,找到x的最小正整数解即可。。

  3.显而易见,a,b一定互质,要不然不可能满足次此方程,即gcd(a,b)==1,那么很显然由②可知,直接套用 扩展欧几里得就好了。 

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int a,b,x,y;
 4 int ex_gcd(int a,int b,int &x,int &y){
 5     if(b==0){
 6         x=1;
 7         y=0;
 8         return a;
 9     }
10     int ans=ex_gcd(b,a%b,x,y);
11     int temp=x;
12     x=y;
13     y=temp-a/b*y;
14     return ans;
15 }
16 int gcd;
17 int main(){
18     cin>>a>>b;
19     int x=0,y=0;
20     gcd=ex_gcd(a,b,x,y);
21     
22     if(x>0){
23         for(int t=0;;t--){
24             if((x+b/gcd*t)<=0){
25                 cout<<x;
26                 return 0;
27             }
28             else{
29                 x=x+b/gcd*t;
30             }
31         }
32     }
33     else{
34         for(int t=0;;t++){
35             if((x+b/gcd*t)>0){
36                 x=x+b/gcd*t;
37                 cout<<x;
38                 return 0;
39             }
40         }
41     }
42     
43     return 0;
44 }

 

 

 

posted @ 2015-08-23 14:54  CXCXCXC  阅读(2167)  评论(0编辑  收藏  举报