Codeforces Round #701 C. Floor and Mod 数学推导
传送门: https://codeforces.com/contest/1485/problem/C
题意
给
一
个
x
和
y
,
求
⌊
a
b
⌋
=
a
m
o
d
b
成
立
的
个
数
。
给一个x和y,求\left \lfloor \frac{a}{b}\right \rfloor =a\;mod\;b成立的个数。
给一个x和y,求⌊ba⌋=amodb成立的个数。
1
≤
a
≤
x
1
≤
b
≤
y
1\leq a \leq x\;\;\;1\leq b \leq y
1≤a≤x1≤b≤y
思路
显
然
这
题
是
围
绕
⌊
a
b
⌋
=
a
m
o
d
b
.
显然这题是围绕\left \lfloor \frac{a}{b}\right \rfloor =a\;mod\;b.
显然这题是围绕⌊ba⌋=amodb.
没
有
限
制
的
话
,
会
有
b
−
1
个
(
0
不
存
在
)
。
没有限制的话,会有\red{b-1}个(0不存在)。
没有限制的话,会有b−1个(0不存在)。
我
们
可
以
手
推
出
3
2
,
4
3
都
可
以
,
并
且
8
3
也
可
以
。
我们可以手推出\frac{3}{2},\frac{4}{3}都可以,并且\frac{8}{3}也可以。
我们可以手推出23,34都可以,并且38也可以。
所
以
b
+
1
b
=
1
,
2
(
b
+
1
)
b
=
2
等
等
。
所以\frac{b+1}{b}=1,\frac{2(b+1)}{b}=2等等。
所以bb+1=1,b2(b+1)=2等等。
所 以 我 们 得 出 来 k ( b + 1 ) b = k = a m o d b 。 k ( b + 1 ) ≤ a 所以我们得出来\frac{k(b+1)}{b}=k=a\;mod\;b。\red{k(b+1)\leq a} 所以我们得出来bk(b+1)=k=amodb。k(b+1)≤a
枚 举 b , 但 是 题 目 是 有 限 制 条 件 的 , 取 m i n 就 行 。 枚举b,但是题目是有限制条件的,取min就行。 枚举b,但是题目是有限制条件的,取min就行。
∑ i = 2 b m i n ( i − 1 , a i + 1 ) \sum_{i=2}^bmin(i-1,\frac{a}{i+1}) i=2∑bmin(i−1,i+1a)
首 先 要 算 一 下 中 间 值 i − 1 = a i + 1 , i = a + 1 , 最 后 得 : 首先要算一下中间值i-1=\frac{a}{i+1},i=\sqrt{a+1},最后得: 首先要算一下中间值i−1=i+1a,i=a+1,最后得:
∑ i = 2 a + 1 i − 1 + ∑ i = a + 1 + 1 b a i + 1 \sum_{i=2}^{\sqrt{a+1}}i-1+\sum_{i=\sqrt{a+1}+1}^b\frac{a}{i+1} i=2∑a+1i−1+i=a+1+1∑bi+1a
前 半 部 分 就 等 差 数 列 求 和 , 后 半 部 分 整 除 分 块 即 可 。 前半部分就等差数列求和,后半部分整除分块即可。 前半部分就等差数列求和,后半部分整除分块即可。
Code(62MS)
#include "bits/stdc++.h"
using namespace std;
typedef long long ll;
void solve() {
int _; cin >> _;
while(_--) {
ll a, b; cin >> a >> b;
ll ans = 0;
ll t = sqrt(a + 1);
if(t > b) {
t = b;
ans += t * (t - 1) / 2;
}
else {
ans += t * (t - 1) / 2;
for (ll l = t + 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;
}
}
signed main() {
solve();
}