题意分析
定义函数
,然后在给定a和b的情况下,求
的值。
思路分析
这个题目就是NC578的加强版。这个题目就是一个公式的推导。
- 这就是数学,一个很复杂的公式推导出了一个简洁的式子。另外,我们发现,这个式子的数据范围过大,可能存在爆long long的写法。所以这里我们使用int128实现。
写法一 迭代法
- 代码如下
- 快速幂和快速乘的写法是log级别的。所以总的时间复杂度是
- 过程中基本没有开其余变量,空间复杂度为
- 快速幂和快速乘的写法是log级别的。所以总的时间复杂度是
class Solution {
public:
/**
*
* @param sa string字符串
* @param sb string字符串
* @param n int整型
* @return long长整型
*/
// 这里用int128实现
typedef __int128 ll;
const ll mod = 10000000033;
// 快速乘写法
ll qc(ll a,ll b){
ll c=0;
while(b){
if(b&1) c=(c+a)%mod;
b>>=1;
// 如果指数为偶数的请款,那么进行迭代处理
a=(a+a)%mod;
}
return c;
}
// 快速幂的写法
ll qp(ll a,ll b){
ll c=1;
while(b){
if(b&1) c=qc(c,a)%mod;
b>>=1;
// 如果指数偶数的情况,那么递归处理
a=qc(a,a)%mod;
}
return c;
}
// 获取字符串对应的具体的数字
ll getnum(string s){
ll sum=0;
for(auto x:s){
sum=sum*10+(ll)(x-'0');
}
return sum;
}
long long solve(string sa, string sb, int n) {
// write code here
ll a=getnum(sa);
// a=(a%mod+mod)%mod;
ll b=getnum(sb);
// b=(b%mod+mod)%mod;
// 特判等号的情况
if(n==0){
return 0;
}else if(n==1){
// 特判为1的情况
ll tmp1=qc(b,b+1)-qc(a,a+1);
tmp1=(tmp1+mod)%mod;
ll down=qp(2,mod-2);
ll ans=qc(tmp1,down);
return ans;
}
ll down=qp(n-1,mod-2);
ll tmp1=qc(b,qp(n,b));
ll tmp2=qc(a,qp(n,a));
ll tmp3=qp(n,b)-qp(n,a);
tmp3=(tmp3%mod+mod)%mod;
tmp3=qc(tmp3,down);
ll tmp=((tmp1-tmp2-tmp3)%mod+mod)%mod;
ll ans=qc(tmp,down);
return ans;
}
};写法二 递归
- 其实在迭代的过程中我们可以使用递归的写法进行代替,这样可能更好理解一点。
- 代码如下
- 快速幂和快速乘的写法是log级别的。所以总的时间复杂度是
- 过程中基本没有开其余变量,空间复杂度为
- 快速幂和快速乘的写法是log级别的。所以总的时间复杂度是
class Solution {
public:
/**
*
* @param sa string字符串
* @param sb string字符串
* @param n int整型
* @return long长整型
*/
// 这里用int128实现
typedef __int128 ll;
const ll mod = 10000000033;
// 快速乘写法
ll qc(ll a,ll b){
if(b==0) return 0;
if(b&1) return (a+qc(a,b-1))%mod;
else{
ll tmp=qc(a,b/2);
// 如果是偶数的情况,那么进行迭代处理
return (tmp+tmp)%mod;
}
}
// 快速幂的写法
ll qp(ll a,ll b){
if(b==0) return 1;
if(b&1) return qc(a,qp(a,b-1));
else{
ll tmp=qp(a,b/2);
// 如果是偶数的情况,那么进行递归处理
return qc(tmp,tmp);
}
}
// 获取字符串对应的具体的数字
ll getnum(string s){
ll sum=0;
for(auto x:s){
sum=sum*10+(ll)(x-'0');
}
return sum;
}
long long solve(string sa, string sb, int n) {
// write code here
ll a=getnum(sa);
// a=(a%mod+mod)%mod;
ll b=getnum(sb);
// b=(b%mod+mod)%mod;
if(n==0){
return 0;
}else if(n==1){
ll tmp1=qc(b,b+1)-qc(a,a+1);
tmp1=(tmp1+mod)%mod;
ll down=qp(2,mod-2);
ll ans=qc(tmp1,down);
return ans;
}
ll down=qp(n-1,mod-2);
ll tmp1=qc(b,qp(n,b));
ll tmp2=qc(a,qp(n,a));
ll tmp3=qp(n,b)-qp(n,a);
tmp3=(tmp3%mod+mod)%mod;
tmp3=qc(tmp3,down);
ll tmp=((tmp1-tmp2-tmp3)%mod+mod)%mod;
ll ans=qc(tmp,down);
return ans;
}
};
京公网安备 11010502036488号