快速幂模板:
int ksm(int b, int p, int k){ int ans = 1 % k; while(p){ if(p & 1) ans = (long long)ans * b % k; b = (long long)b * b % k; p >>= 1; } return ans; }
思想是将指数p分解为二进制处理.由于结果数值经常很大,题目一般只要求给出取模后的答案.
而取模具有传递性,至少在只进行加减乘运算时,过程中何时取模,取多少次模都不会影响最终答案,前提是过程中不发生溢出.
注意这里取模对象是int,故取模后一定是int范围内的数值,但是要注意int与int相乘是会越过int范围的,需要先进行(long long)强制转换,取模后范围变回int再赋值.
具体分析:
将p分解为:
p=a020+a121+a222+a323+...+ak-12k-1,(p转化为二进制表示有k位)其中,ai=0或1,
则bp=ba02^0*ba12^1*ba22^2* ... *bak-12^(k-1).所以设ans为1,从最低位开始对p的每一位进行处理,若该位为1,则ans乘以左式对应的乘积项.位为0对应的乘积项显然都变为了1,不需要相乘.
发现在忽略ai的情况下,一个乘积项总是上一个乘积项的两倍,因此设置一个变量记录这个以2累乘的过程值便于计算.
复杂度分析:
上述过程的while循环进行了log p次,即复杂度为O(log n).这是比一遍遍地累乘原数值要快的(O(p),p为指数).