nowCoder 计数器
有一个计数器,计数器的初始值为0,每次操作你可以把计数器的值加上 a 1 , a 2 , . . . , a n a_1,a_2,...,a_n a1,a2,...,an中的任意一个整数,操作次数不限(可以为0次),问计数器的值对m取模后有几种可能。
输入描述:
第一行两个整数 n , m n,m n,m
接下来一行n个整数表示 a 1 , a 2 , . . . , a n a_1,a_2,...,a_n a1,a2,...,an
1 ≤ n ≤ 100 1≤n≤100 1≤n≤100
1 ≤ m , a 1 , a 2 , . . . , a n ≤ 1000000000 1≤m,a_1,a_2,...,a_n≤1000000000 1≤m,a1,a2,...,an≤1000000000
输出描述:
输出一个整数表示答案
示例1
输入
3 6
6 4 8
输出
3
AC代码
#include<iostream>
#include<algorithm>
using namespace std;
int main(){
ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
int n, m, g, a;
cin >> n >> m;
g = m;
for(int i = 1; i <= n; i++){
cin >> a;
g = __gcd(a, g);
}
cout << m / g << endl;
return 0;
}
代码分析
1.裴蜀定理
若 a , b a,b a,b是整数,且 g c d ( a , b ) = d gcd(a, b)=d gcd(a,b)=d,那么对于任意整数 x , y , a x + b y x,y,ax+by x,y,ax+by都一定是 d d d的倍数,特别地,一定存在整数 x , y x,y x,y,使得 a x + b y = d ax+by=d ax+by=d成立
由上述定理描述可知:
a
1
x
1
+
a
2
x
2
+
.
.
.
+
a
n
x
n
=
P
∗
g
c
d
(
a
1
,
a
2
,
a
3
,
.
.
.
,
a
n
)
(
P
为
整
数
)
a_1x_1+a_2x_2+...+a_nx_n=P*gcd(a_1,a_2,a_3,...,a_n)(P为整数)
a1x1+a2x2+...+anxn=P∗gcd(a1,a2,a3,...,an)(P为整数)
由题意有
(
a
1
x
1
+
a
2
x
2
+
a
3
x
3
+
.
.
.
+
a
n
x
n
)
%
m
=
r
(a_1x_1+a_2x_2+a_3x_3+...+a_nx_n)\%m=r
(a1x1+a2x2+a3x3+...+anxn)%m=r
将取模运算进行转化(
k
k
k为商,
r
r
r为余数):
(
a
1
x
1
+
a
2
x
2
+
a
3
x
3
+
.
.
.
+
a
n
x
n
)
=
k
m
+
r
(a_1x_1+a_2x_2+a_3x_3+...+a_nx_n)=km+r
(a1x1+a2x2+a3x3+...+anxn)=km+r
r
=
a
1
x
1
+
a
2
x
2
+
a
3
x
3
+
.
.
.
+
a
n
x
n
−
k
m
r=a_1x_1+a_2x_2+a_3x_3+...+a_nx_n-km
r=a1x1+a2x2+a3x3+...+anxn−km
由裴蜀定理有:
r
=
a
1
x
1
+
a
2
x
2
+
a
3
x
3
+
.
.
.
+
a
n
x
n
+
(
−
k
)
m
=
P
∗
g
c
d
(
a
1
,
a
2
,
a
3
,
.
.
.
,
a
n
,
m
)
r=a_1x_1+a_2x_2+a_3x_3+...+a_nx_n+(-k)m=P*gcd(a_1,a_2,a_3,...,a_n,m)
r=a1x1+a2x2+a3x3+...+anxn+(−k)m=P∗gcd(a1,a2,a3,...,an,m)
假设
g
c
d
(
a
1
,
a
2
,
a
3
,
.
.
.
,
a
n
,
m
)
=
A
gcd(a_1,a_2,a_3,...,a_n,m)=A
gcd(a1,a2,a3,...,an,m)=A则有
r
=
P
∗
A
(
A
为
常
数
)
r=P*A(A为常数)
r=P∗A(A为常数)
因为
P
P
P在本题中为正整数,则
P
P
P可取
0
,
1
,
2
,
.
.
.
,
P
m
a
x
0,1,2,...,P_{max}
0,1,2,...,Pmax且每个取值对应一个
r
r
r,故求出
P
m
a
x
P_{max}
Pmax即可知道对应的余数
r
r
r可能个数
P = r g c d ( a 1 , a 2 , a 3 , . . . , a n , m ) P=\frac r {gcd(a_1,a_2,a_3,...,a_n,m)} P=gcd(a1,a2,a3,...,an,m)r
因为 r r r为余数,由余数必小于除数有 r < m r<m r<m有
P = r g c d ( a 1 , a 2 , a 3 , . . . , a n , m ) < m g c d ( a 1 , a 2 , a 3 , . . . , a n , m ) P=\frac r {gcd(a_1,a_2,a_3,...,a_n,m)} < \frac m {gcd(a_1,a_2,a_3,...,a_n,m)} P=gcd(a1,a2,a3,...,an,m)r<gcd(a1,a2,a3,...,an,m)m
P m a x = m g c d ( a 1 , a 2 , a 3 , . . . , a n , m ) P_{max}=\frac m {gcd(a_1,a_2,a_3,...,a_n,m)} Pmax=gcd(a1,a2,a3,...,an,m)m
该除式自动向下取整,故问题得解
2.最大公约数 g c d gcd gcd
typedef ll long long;
ll gcd(ll a, ll b){
return b == 0 ? a : gcd(b, a % b);
}