POJ1845_Sumdiv
描述
给定A、B,求A的B次方的所有因数在模9901意义下的和。
数据范围
A、B在0~50000000内
思路
首先,根据算术基本定理对A进行分解:
A=p1^c1×p2^c2×……×pn^cn
那么A^B的分解为:
A^B=p1^(c1×B)×p2^(c2×B)×……×pn^(cn×B)
我们可以把A^B的因子分为:不含p1的,含一个p1的,含两个p1的……
那么显然,所有不含p1的因子和若为x,那么含一个p1的因子和为xp1,以此类推,总和为:
(1+p1+p1^2+……+p1^Bc1)×(不含p1的因子和)
继续类推得:
总和=(1+p1+p1^2+……+p1^Bc1)×(1+p2+p2^2+……+p2^Bc2)×……×(1+pn+pn^2+……+pn^Bcn)
这样,我们只需要做因子分解,并计算等比数列即可。
因子分解的做法简单,不表。
等比数列的计算虽有公式,但公式涉及除法,在本题取模意义下需要求逆元。
利用分治的思想:
若n是奇数,则取h=(n>>1)
并令1+p+p^2+……+p^n=cal(p,n)
有cal(p,n)=cal(p,h)×(1+p^(h+1))
若n是偶数,则取h=(n>>1)-1
在上面结果的基础上再加p^n即可。
使用快速幂+分治的思想可以把等比数列求和复杂度限制在O(logc)
解决
1 |
|
反思和坑
本题的数据范围比较大,虽然模数很小,但是计算指数和因子的时候仍有可能越界。
不知道有没有底数是0的情况,如果有,需要特判。不过感觉应该没有。
另一种做法
在数论中,取模意义下的除法可以用乘以其逆元的方式实现
因此,我们可以
1.分解因数
2.使用快速幂计算通项公式分子
3.求出分母的逆元
注意,当分母是9901的倍数时不存在逆元,就不能使用通项公式,但此时可以推导出pmod9901=1,因此也比较好算
解决
1 | #include <cstdio> |
POJ3889_Fractal Streets
描述
某个城市的初始状态如下图的等级1,每当城市扩大一个等级时,它的面积扩大4倍,并将原结构复制,放在城市上方,顺时针旋转90度的原结构放在左上方,逆时针旋转90度的原结构放置在右上方。
现在,居住在城市中的Chris有一辆飞行车,这意味着他可以实现两点之间的直线飞行。给出城市的等级和两个点的编号,求出其直线距离。
假设所有的方格10米见方,并且每个点都在方格的正中心。距离要求输出四舍五入的正整数。
数据范围
城市规模小于16,点编号小于2的31次方。
思路
不论城市的规模为几,都可以划分为四个大块,同时,根据城市的规模和其旋转朝向,可以唯一确定一个城市。
首先计算出某个点在哪个大块中。
然后,将这个大块看作一个子城,计算出新的规模和旋转朝向,新的点编号。
解决
1 |
|
反思和坑
注意四舍五入,double直接转换为int是截断而不是四舍五入。
注意long long,因为计算坐标的时候可能会超出int的范围。