Wannafly挑战赛22 - A - 裴蜀定理

链接:https://www.nowcoder.com/acm/contest/160/A
来源:牛客网
 

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld

题目描述

有一个计数器,计数器的初始值为0,每次操作你可以把计数器的值加上a1,a2,...,an中的任意一个整数,操作次数不限(可以为0次),问计数器的值对m取模后有几种可能。

输入描述:

第一行两个整数n,m
接下来一行n个整数表示a1,a2,...,an
1≤n≤100
1≤m,a1,a2,...,an≤1000000000

输出描述:

输出一个整数表示答案

 

示例1

输入

复制

3 6
6 4 8

输出

复制

3

思路:

裴蜀定理:

  • 对于任何整数a,b且gcd(a,b)=d,那么对于任意的整数x,y,ax+by都一定是d的倍数,特别的,一定存在整数x,y使得ax+by=d成立。

重要推论:

  • a,b互质的充要条件是存在整数x,y使得ax+by=1。

假设对数an取的个数为kn,可得到如下等式:

a1*k1+a2*k2+a3*k3+......an*kn=p

设g=gcd(a1,a2,a3...an)

当p为g的倍数时,等式有解。

注意:这里求公约数的是时候要把m也算进去。

g=gcd(a1,a2...an)  设g*x%m=a,(a是模m后的值,不同的a的个数就是答案)

则有 gx-my=a,裴蜀定理,若想要等式有解a必须为gcd(g,m)的倍数。又因为a是模m后的值,则答案是:m/gcd(g,m)(在m内能有几个a成立)

代码如下:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<string>
#include<cstring>
#include<vector>
#include<map>
using namespace std;
#define ll long long
ll gcd(ll a,ll b){
    if(a<b)swap(a,b);
    if(b==0)return a;
    return gcd(b,a%b);
}
int main(){
    ll n,m;
    scanf("%lld%lld",&n,&m);
    ll tmp=m,a;
    for(int i=0;i<n;i++){
        scanf("%lld",&a);
        tmp=gcd(tmp,a);
    }
    printf("%lld\n",m/tmp);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值