nowCoder:计数器(gcd裴蜀定理应用)

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 1n100
1 ≤ m , a 1 , a 2 , . . . , a n ≤ 1000000000 1≤m,a_1,a_2,...,a_n≤1000000000 1m,a1,a2,...,an1000000000
输出描述:
输出一个整数表示答案
示例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=Pgcd(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+...+anxnkm
由裴蜀定理有:
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=Pgcd(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=PA(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);
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值