·问题描述·
有一个密码箱,0到n-1中的某些数是它的密码。且满足:如果a和b都是它的密码,那么(a+b)%n也是它的密码。某人试了k次密码,前k-1次都失败了,最后一次成功。
问:该密码箱最多有多少个密码?
·输入格式·
输入第一行两个整数分别表示n,k。
第二行为k个用空格隔开的非负整数,表示每次试的密码。(数据保证存在合法解)
·输出格式·
输出一行一个数,表示结果。
·输入样例·
42 5
28 31 10 38 24
·输出样例·
14
·数据范围·
对于100%的数据:1<=k<=250000,k<=n<=10^14。
Solution:
本题考察数学。由题意可知,若x为密码则(x+x)%n为密码,则p*x%n(0
由引理:a*x+b*y=c(均为整数),有整数解的充要条件是gcd(a,b)|c。证明很容易:不妨设a=p*gcd(a,b),b=q*gcd(a,b) --> a*x+b*y=(p+q)*gcd(a,b)=c,显然要有整数解,则gcd(a,b)|c。 回到本题的条件:p*x-n*c=q。有解则必定满足gcd(x,n)|q,所以必定有p*x-n*c=gcd(x,n)成立,等价于p*x%n=gcd(x,n),则gcd(x,n)一定为一个密码。类似的,对于不同的密码x和y,存在(p*x+q*y)%n为密码,由引理必定存在p*x+q*y=gcd(x,y),与单个x是密码同理gcd(x,y)一定是密码。 而要使得密码最多,由x是密码则p*x%n(0 为密码可知,当x为最小时,密码最多有n/x个。 具体实现时,我们先求出a[k]=gcd(a[k],n),再使a[i]=gcd(a[i],a[k]),然后从新的a[k]中删去所有是a[i]因子的因子,最后输出答案就是n除以没被删的最小的因子。 代码: 1 /*数学一本通上的例题——by 520*/
2 #include