本题关键——费马小定理
牛牛的函数
http://www.nowcoder.com/questionTerminal/9d90c461f30e46d29500fbc0d9a24634
首先看到题目我选择了暴力加法,结果毫无疑问地超时了......
接着看别人的代码再自己查资料, 我有了思路
从n的a次方累加到n的b次方可以用等比数列求和公式得到 f(n) = (n^(b+1) - n^a)/(n-1)
要求f(n) % 10000000033, n-1是一个很麻烦的地方,由此我找到了一个数学定理————费马小定理
费马小定理讲的是如果p是一个质数,而整数x不是p的倍数,则有x^(p-1)%p = 1;
这里10000000033是一个质数,而n-1显然不是其倍数,满足条件
两边同时除以x得到x^(p-2) % p = 1/x % p;
即(y/x)%p = y%p * (1/x)%p = y%p * x^(p-2)%p;
(这里令p=10000000033, y = n^(b+1)-b^a, x=n-1)
解决了这一个问题,下一个问题来了,要是a和b的值很大,那么来求n^(b+1)而保证不超出long long的限制呢
看大神们的代码,我知道了快速幂的方法
在以上的基础上,我发现我的代码还是不能AC,又上网查了一下,才知道在我的快速幂计算过程中还是可能会超过long long的限制,还需要使用快速乘法来得到余数。
#define ll long long const ll MOD=10000000033; class Solution { public: //快速乘法 ll ksc(ll x,ll y) { return (x*y-(ll)((long double)x/MOD*y)*MOD+MOD)%MOD; } //快速幂 ll quickPow(int x,ll b) { ll base=x,res=1; while(b) { if(b&1) res=ksc(res,base); b>>=1; base=ksc(base,base); } return res; } long long solve(int a,int b,int n) { if(n==0) return 0; if(n==1) return b-a+1; ll res=(quickPow(n,b+1)-quickPow(n,a)+MOD)%MOD; //费马小定理求逆元 ll inv=quickPow(n-1, MOD-2); return ksc(res,inv); } };