定义函数 f(x) = x^a + x^(a+1) +...+ x^(b-1) + x^b,然后在给定a和b的情况下,求f(x)%10000000033的值。
typedef long long ll; class Solution { public: /** * * @param a int整型 * @param b int整型 * @param n int整型 * @return long长整型 */ const ll M = 10000000033; ll F(ll x, ll y){ ll s = 0; x %= M; y %= M; while(y){ if(y&1){ s += x; if(s>=M) s -= M; } y>>=1; x<<=1; if(x>=M) x -= M; } return s; } ll P(ll x, ll y){ ll s = 1; while(y){ if(y&1) s = F(s, x); x = F(x, x); y>>=1; } return s; } long long solve(int a, int b, int n) { if(n==0) return 0; if(n==1) return b-a+1; ll s = (P(n, b+1)-P(n, a)+M) % M; ll t = P(n-1, M-2); return F(s ,t); } };
题意:求(n^a + n^(a + 1) +...+n^b ) % 10000000033的值。
数据范围:
0<=x,a,b<=1e9, 且 a<=b
前置知识: 同余
思路1:
由于题目数据范围巨大,故 不能使用常规幂运算 进行计算;需要使用快速幂进行加速计算,并且使用快速乘法来防止数据溢出,但是由于此方法需要遍历a ~ b,并且每次遍历有两次快速幂计算,时间复杂度为n(log(n * logn)),因此会超时。
思路2:
在思路1 的基础上,通过 等比数列求和公式 和求 逆元 进行优化。
#define LL long long const LL mod = 10000000033; class Solution { public: //快速乘法 LL quick_mul(LL a,LL b){ a%=mod; b%=mod; LL res=0; while(b){ if(b&1){ res+=a; if(res>=mod) res-=mod; } b>>=1; a<<=1; if(a>=mod) a-=mod; } return res; } LL quick_pow(LL a, LL b){ LL res = 1; while(b){ if(b&1){ res = quick_mul(res, a); } a = quick_mul(a, a); b >>= 1; } 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=(quick_pow(n, b + 1)- quick_pow(n, a)+ mod) % mod; //费马小定理求逆元 LL inv=quick_pow(n - 1, mod - 2); return quick_mul(res,inv); } };
long long solve(int a, int b, int n) { // write code here if(n == 0) { return 0; } long long s = 1; for(int i = 0; i < b - a; i++) { s = 1 + (n * s) % 10000000033; } for(int i = 0; i < a; i++) { s = (s * n) % 10000000033; } return s; }这么写复杂度就是O(b), 但是**超时了,不知道该怎么写了?难道和这个 10000000033有关