版权声明:本文为博主原创文章,转载请预先通知博主(〃'▽'〃)。 https://blog.csdn.net/m0_37624640/article/details/82667065
做法:
- 裴蜀定理:若a,b是整数,且(a,b)=d,那么对于任意的整数x,y,ax+by=k中的k一定是d的倍数。
- 现在我们知道n个数,a1,a2,a3,……,an。我们把他们通过gcd联系起来
- 设gcd(a1,a2,a3,……,an) = p
- 那么一定存在一组解k1,k2,……,kn 使得 a1*k1+a2*k2+……+an*kn = k*P (k为任意整数) 即裴蜀定理
- 那么我们想求得其实就是(k*p)%m,通过找规律发现这个式子是存在循环节的。
- 举个栗子:
- a1 = 12,a2 = 3, gcd(a1,a2) = 3 另m = 12
- (a1)% m = 0
- (a1+a2)%m = 3
- (a1+2*a2)%m = 6
- (a1+3*a2)%m = 9
- (a1+4*a2)%m = 0
- (a1+5*a2)%m = 3
- ……………………
- 所以我们只要求出循环节的头和尾就知道有几个mod (m) 不同值的个数了
- 我们发现0也是gcd(a,b)的倍数,所以直接使得(k*p)%m = 0 转换一下 变成 k*p-m*k1 = 0
- 我们令a = p, b = m , x = k, y = -k1 ,即转换成了ax+by = 0
- 由扩展欧几里得可知存在一个通解公式x = x0+b/(gcd(a,b)) *t = x0 + m/(gcd(p,m)) *t
- 我们再x0 = 0,那么循环节的个数就是m/(gcd(p,m)) 即mod(m) 不值的个数
AC代码:
#include<bits/stdc++.h>
#define IO ios_base::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#define pb(x) push_back(x)
#define sz(x) (int)(x).size()
#define sc(x) scanf("%d",&x)
#define pr(x) printf("%d\n",x)
#define abs(x) ((x)<0?-(x):x)
#define all(x) x.begin(),x.end()
using namespace std;
typedef long long ll;
const int mod = 1e9+7;
const double PI = 4*atan(1.0);
const int maxm = 1e8+5;
const int maxn = 1e4+5;
const int INF = 0x3f3f3f3f;
int gcd(int a,int b){return b?gcd(b,a%b):a;}
int a[105];
int main()
{
#ifdef LOCAL_FILE
freopen("in.txt","r",stdin);
#endif // LOCAL
IO;
int n,m;
cin>>n>>m;
for(int i=0;i<n;i++) cin>>a[i];
int ans = gcd(a[0],a[1]);
for(int i=2;i<n;i++) ans = gcd(ans,a[i]);
cout<<m/gcd(ans,m)<<endl;
return 0;
}