HDOJ-----1576拓展欧几里德

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

Input
数据的第一行是一个T,表示有T组数据。
每组数据有两个数n(0 <= n < 9973)和B(1 <= B <= 10^9)。
 

Output
对应每组数据输出(A/B)%9973。
 

Sample Input
  
  
2 1000 53 87 123456789
 

Sample Output
  
  
7922 6060



题解1

根据拓展欧几里德,Ax + By = g(A,B)必定有解

由题得A % 9973 = n,A = 9973y + n,A / B = x,所以Bx - 9973y = n

根据g(A,B) = 1,不必判断c是gcd(A,B)的倍数

利用扩展欧几里得模板计算Bx - 9973y = n的最小整数解即可

#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<string>
#include<algorithm>
#include<map>
#include<set> 
#include<queue>
#include<vector>
#include<functional>
#define PI acos(-1.0)
#define INF 0x3f3f3f3f
#define CL(a, b) memset(a, b, sizeof(a))
using namespace std;
typedef long long LL;
const int maxn = 1e5+10;
const int MOD = 1e9+7; 
int n[20], m[20];
void ex_gcd(LL a, LL b, LL& d, LL& x, LL& y){
	if(!b){
		d = a;
		x = 1;
		y = 0;
	}
	else{
		ex_gcd(b, a%b, d, y, x);
		y -= x*(a/b);
	}
}
int main(){
	LL t, n, a, b, c, d, A, B, C, k, x, y;
	int kcase = 1;
	scanf("%lld", &t);
	while(t--){
		scanf("%lld%lld", &n, &B);
		a = B;
		b = 9973;
		c = n; 
		ex_gcd(a, b, d, x, y);
		c /= d;
		x *= c;
		b /= d;
		x = (x%b+b)%b;
		printf("%lld\n", x);
	}
	return 0;
}

题解2

设  A=B*N;

     根据同余定理 : A % 9973 =  (B % 9973 )*(N % 9973)% 9973

     N % 9973为所求   又因为 N % 9973 属于【0,9972】 所以枚举N % 9973的值,设N % 9973 = i满足条件则输出


#include<stdio.h>
int main(){
    int i,t,x;
      scanf("%d",&t);
    while(t--){
        long long n, b;
        scanf("%lld%lld", &n, &b);
        for(i = 0; i < 9973; i++){
            if((b * i - n) % 9973 == 0){
                x = i;
                break;
            }
        }
        printf("%d\n",x);
    }
    return 0;
}

 
 
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值