C. Border(exgcd/裴蜀定理)

https://codeforces.com/problemset/problem/1010/C

题意翻译

NatashaNatasha 抵达了火星.

火星上的钞票面额有nn种,第ii种的价值是a_iai​。NatashaNatasha 每个面额的钞票都有无数张。

火星人有kk个手指,所以他们使用kk进制。此外,火星人认为数字dd(在kk进制中)是神圣的。因此,如果凑出来的钱中在kk进制中最后一位数字是dd,火星人会很高兴。不幸的是,NatashaNatasha 还不知道dd是几。所以,他想知道他能凑出哪些数字。

输入输出样例

输入 #1复制

2 8
12 20

输出 #1复制

2
0 4 

输入 #2复制

3 10
10 20 30

输出 #2复制

1
0 

思路:首先看到k进制的最后一位数是每个数modk,然后这样暴力去统计的话还是无限个,所以一定不是这个方向。

正解:用到了exgcd的性质。

ax+by=c的不定方程有解的充要条件是c是gcd(a,b)的倍数。

所以多于多个数字而言,c是gcd(x1,x2,x3,x4...xn)的倍数。

既然是倍数而且题目说是无限个,所以只要求出了这个c,那么接下来后面的数只会是c的倍数。

比如c=gcd(x1,x2,x3),那么c肯定满足gcd(x1,x2),所以求出了c=gcd(x1,x2,x3....xn)后,然后枚举倍数0,1,2,3.....看c*i%k是不是出现过,出现过就停止,不然就继续枚举。

特别的当c=1时候,说明互质,也就是在k以内的1的倍数都可以取到。

#include
#include
#include
#include
#include
#include
#include
#include
#include
#define debug(a) cout<<#a<<"="<>n>>k;
  for(LL i=1;i<=n;i++) cin>>a[i];
  LL res=0;
  for(LL i=1;i<=n;i++){
  	a[i]%=k;
  	res=__gcd(res,a[i]);
  }
  //debug(res);
  if(res==1){
  	cout<

 

你可能感兴趣的:(数论,exgcd)