Floor and Mod(CF1485C)(数论)
题意:
问多少对 \(a,b\) 满足 \(\lfloor \frac{a}{b} \rfloor =a\ mod\ b\) 。
其中 \(1\leqslant a\leqslant x,1\leqslant b\leqslant y\) 。
想法:
- \(\lfloor \frac{a}{b} \rfloor =a\ mod\ b\) 如果对于 \(a\) 没有限制的话,对于每个 \(b\) 那么答案就是 \(b-1\) 个 ( \(0\sim (b-1)\) 只有 \(0\) 不符合。
- 考虑对于一个 \(b\) 确定,哪些 \(a\) 会满足答案。如 \(\frac{b+1}{b}、\frac{2\times (b+1)}{b}...\)都满足,那么就可以得到 $\frac{k\times (b+1)}{b} = (k\times (b+1))\ mod\ b $ 满足。
- 由于 \(k\times (b+1)\) 的取值范围是 \(1\sim x\),那么对于每个 \(b\),在这个取值范围内可取答案数量就是 \(\lfloor \frac{x}{b+1} \rfloor\)。
- 所以最终答案就是
.\(\sum^{y}_{b=2} min(b-1,\frac{x}{b+1} )\)。 - 接下来考虑这个式子怎么求。把这个式子分成两部分,那么分界点就是 \(b-1=\frac{x}{b+1}\) 时,也就是 $b=\sqrt{x+1} $ 时,那么答案就是
.\(\sum^{\sqrt{x+1}}_{b=2} b-1 +\sum^{\ \ \ \ \ \ \ \ y}_{b=\sqrt{x+1}+1} \frac{x}{b+1}\) - 对于前半部分,就是等差数列求和。对于下半部分,考虑数论分块
- 需要注意的就是在分块的过程中区间选取时,对于 \(b\)的枚举不能超过 \(x\)且区间末端不能超过 \(x,y\)。
代码:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int mod=1e9+7;
const int maxn=100005;
int main()
{
int T;
ll a,b;
cin>>T;
while(T--){
scanf("%lld%lld",&a,&b);
ll num=sqrt(a+1);
ll ans=0;
if(num>b){
num=b;
ans+=(num)*(num-1)/2;
}else{
ans+=(num)*(num-1)/2;
for(ll l=num+1,r;l<=min(a,b);l=r+1){
if(a/(l+1)==0)break;
else{
r=min(b,min(a,a/(a/(l+1))-1));
}
ans+=(r-l+1)*(a/(l+1));
}
}
cout<<ans<<endl;
}
return 0;
}
越自律,越自由