您的位置:首页 > 其它

【扩展欧几里得】hdu 1576 A/B

2017-10-05 19:12 477 查看

A/B

                            Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
                                                    Total Submission(s): 639    Accepted Submission(s): 517

[align=left]Problem Description[/align]
要求(A/B)%9973,但由于A很大,我们只给出n(n=A%9973)(我们给定的A必能被B整除,且gcd(B,9973) = 1)。
 
 

[align=left]Input[/align]
数据的第一行是一个T,表示有T组数据。

每组数据有两个数n(0 <= n < 9973)和B(1 <= B <= 10^9)。
 
 

[align=left]Output[/align]
对应每组数据输出(A/B)%9973。
 
 

[align=left]Sample Input[/align]

2 1000 53 87 123456789

 
 

[align=left]Sample Output[/align]

7922 6060

 

逆元解法:
#include<stdio.h>
#define MOD 9973
//******************************
//返回d=gcd(a,b);和对应于等式ax+by=d中的x,y
long long extend_gcd(long long a,long long b,long long &x,long long &y)
{
if(a==0&&b==0) return -1;//无最大公约数
if(b==0){x=1;y=0;return a;}
long long d=extend_gcd(b,a%b,y,x);
y-=a/b*x;
return d;
}
//*********求逆元素*******************
//ax = 1(mod n)
long long mod_reverse(long long a,long long n)
{
long long x,y;
long long d=extend_gcd(a,n,x,y);
if(d==1) return (x%n+n)%n;
else return -1;
}

int main()
{
int T;
int n,B;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&B);
int x=mod_reverse(B,MOD);
printf("%d\n",n*x%MOD);
}
return 0;
}

扩展欧几里得求ax+by=c解法:
先设(A/B)%9973 = k
--->> A/B = k + 9973 * x
--->> A = kB + 9973*x*B
--->> kB % 9973 = n
--->> 则kB = n + 9973 * y
--->> 则 kB + 9973 *y = n,y属于整数,可正可负
--->>(k / n) * B + 9973*(y / n) = 1
--->> 又gcd(B,9973)= 1
--->> 所以求出k = x *n %9973
#include <iostream>
#include <set>
#include <map>
#include <stack>
#include <cmath>
#include <queue>
#include <cstdio>
#include <bitset>
#include <string>
#include <vector>
#include <iomanip>
#include <cstring>
#include <algorithm>
#include <functional>
#define PI acos(-1)
#define eps 1e-8
#define inf 0x3f3f3f3f
#define debug(x) cout<<"---"<<x<<"---"<<endl
typedef long long ll;
using namespace std;

///求ax+by=gcd(a,b)的特解x0,y0以及gcd(a,b)
long long exgcd(long long a, long long b, long long &x, long long &y)
{
if (b == 0)
{
x = 1;
y = 0;
return a;
}
long long ans = exgcd(b, a % b, x, y);
long long temp = x;
x = y;
y = temp - (a / b) * y;
return ans;  ///ans=gcd(a,b);
}
///求ax=c(mod b),即求ax+by=c的最小非负整数解
long long cal(long long a, long long b, long long c)
{
long long x, y;
long long gcd = exgcd(a, b, x, y);
if (c % gcd != 0)
{
return -1;
}
x = x * (c / gcd);
int t = b / gcd;
if (t < 0)
{
t = -t;
}
long long ans = x % t;
if (ans <= 0)
{
ans += t;
}
return ans;
}
int main()
{
long long t, n, b;
cin >> t;
while (t--)
{
cin >> n >> b;
long long ans = cal(b, 9973, 1);
cout << ans*n % 9973 << endl;
}
return 0;
}
///求ax+by=c的特解:
///x0=x0*(c/gcd);
///y0=y0*(c/gcd);

///求通解:
///x=x0+(b/gcd)*k;
///y=y0-(a/gcd)*k;

/************************************************
┆  ┏┓   ┏┓ ┆
┆┏┛┻━━━┛┻┓ ┆
┆┃       ┃ ┆
┆┃   ━   ┃ ┆
┆┃ ┳┛ ┗┳ ┃ ┆
┆┃       ┃ ┆
┆┃   ┻   ┃ ┆
┆┗━┓    ┏━┛ ┆
┆  ┃    ┃  ┆      
┆  ┃    ┗━━━┓ ┆
┆  ┃  AC代马   ┣┓┆
┆  ┃           ┏┛┆
┆  ┗┓┓┏━┳┓┏┛ ┆
┆   ┃┫┫ ┃┫┫ ┆
┆   ┗┻┛ ┗┻┛ ┆
************************************************ */
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  数论 hdu 算法