ACM训练半周总结—11月16日

来源:互联网 发布:python 区分中英文 编辑:程序博客网 时间:2024/05/29 11:44

        这个半周一只在努力做题,可越做越感觉力不从心,尤其数论2这个专题与比1有所提升,学习博客的知识点明显不够。也确实感到数学+ACM=我缺知识点。还是总结下题目吧。

         W题:给出一个整数n,求小于n的且与n是非质数的和。

         定理:如果n与m互质(n>m),那么n-m与n互素。。。。。小本本

         那么此时这个就可以先求出前n-1项的和,再减去n*oula(n)/2;

        U题给出n和m,求x(1<=x<=n)有gcd(x,n)>=m。求符合条件的个数。

        这道题先假设gcd(x,n)=a,x=ab,n=ac,那么可以知道,b和c互素且b<c。那么这道题就可以找出所有可以整除n的因子,如果因子>=m,就累加小于n/因子。当然要注意还要将时间优化用sqrt(n),同时处理 i 与n/i,进行判断。

        C题:给一个数p,求以p为模素的原根个数。原根定义:{ (n^i mod p) | 1 <= i <= p-1 }是{ 1, ..., p-1 },求满足条件的n。

        定理: 如果p有原根,那么p一共有oula(oula(p))个原根。

        A题:之前做过,就是中国剩余定理,人情感,体力,智力有三周期23,28,33,分别给出三个的计算开始日期,求n以后出现的三日期同一天在那天。

        关于这道题我之前有看了一篇不错的文章

转载于http://blog.csdn.net/dafang_xu/article/details/50818919

中国剩余定理分析 
我们将“孙子问题”拆分成几个简单的小问题,从零开始,试图揣测古人是如何推导出 
这个解法的。

这就牵涉到一个最基本数学定理,如果有a%b=c,则有(a+kb)%b=c(k 为非零整数),换句 
话说,如果一个除法运算的余数为 c,那么被除数与 k 倍的除数相加(或相减)的和(差) 
再与除数相除,余数不变。这个是很好证明的。

以此定理为依据,如果n2 是3 的倍数,n1+n2 就依然满足除以3 余2。同理,如果n3 
也是3 的倍数,那么n1+n2+n3 的和就满足除以3 余2。这是从n1 的角度考虑的,再从n2, 
n3 的角度出发,我们可推导出以下三点:
为使n1+n2+n3 的和满足除以3 余2,n2 和n3 必须是3 的倍数。 
为使n1+n2+n3 的和满足除以5 余3,n1 和n3 必须是5 的倍数。 
为使n1+n2+n3 的和满足除以7 余2,n1 和n2 必须是7 的倍数。 
因此,为使n1+n2+n3 的和作为“孙子问题”的一个最终解,需满足:
n1 除以3 余2,且是5 和7 的公倍数。 
n2 除以5 余3,且是3 和7 的公倍数。 
n3 除以7 余2,且是3 和5 的公倍数。 
所以,孙子问题解法的本质是从5 和7 的公倍数中找一个除以3 余2 的数n1,从3 和7 
的公倍数中找一个除以5 余3 的数n2,从3 和5 的公倍数中找一个除以7 余2 的数n3,再将 三个数相加得到解。 
在求n1,n2,n3 时又用了一个小技巧,以n1 为例,并非从5 和7 的公 倍数中直接找一个除以3 余2 的数,而是先找一个除以3 余1 的数,再乘以2。
这里又有一个数学公式,如果a%b=c,那么(a*k)%b=(a%b+a%b+„+a%b)%b=(c+c+„+c)%b=kc%b(k>0), 
也就是说,如果一个除法的余数为c,那么被除数的k 倍与除数相除的余数为kc。展开式中 
已证明。
最后,我们还要清楚一点,n1+n2+n3 只是问题的一个解,并不是最小的解。如何得到最 
小解?我们只需要从中最大限度的减掉掉3,5,7 的公倍数105 即可。道理就是前面讲过的 
定理“如果a%b=c,则有(a-kb)%b=c”。所以(n1+n2+n3)%105 就是最终的最小解。 
总结 
经过分析发现,中国剩余定理的孙子解法并没有什么高深的技巧,就是以下两个基本数学 
定理的灵活运用: 
如果 a%b=c , 则有 (a+kb)%b=c (k 为非零整数)。 
如果 a%b=c,那么 (a*k)%b=kc%b (k 为大于零的整数)。

        S题:输入x,求2004^x%29。

        一个数的的因子和是积性函数。设S(x)表示x的因子和,如果x可以被分解为素数x=a*b,那么S(x)=S(a)*S(b)。

如果 p 是素数 则其因子只有1和它本身,S(p^X)=1+p+p^2+...+p^X = (p^(X+1)-1)/(p-1)


所以:S(2004^X)=(2^(2X+1)-1) * (3^(X+1)-1)/2 * (167^(X+1)-1)/166
考虑到 167%29 == 22
原式可写为     S(2004^X)=(2^(2X+1)-1) * (3^(X+1)-1)/2 * (22^(X+1)-1)/21。
(a*b)/c %M= a%M * b%M * inv(c)
其中inv(c)即满足 (c*inv(c))%M=1的最小整数,用术语讲,inv(c)表示c在模p下的乘法逆元
这里M=29      则inv(1)=1,inv(2)=15,inv(22)=15
原式可写为: S(2004^X)=(2^(2X+1)-1) * (3^(X+1)-1)/2 * (22^(X+1)-1)/21
=(2^(2X+1)-1) * (3^(X+1)-1)*15 * (22^(X+1)-1)*18

乘法的逆元:如果ax≡1 (mod p),且gcd(a,p)=1(a与p互质),则称a关于模p的乘法逆元为x