题目描述
给定一个正整数a,对于所有的正整数b,求a%b可能有多少种不同的值?
输入
一个整数a, 1 ≤ a ≤ 1 0 18 1≤a≤10^{18} 1≤a≤1018
输出
一个整数,a%b可能出现的不同的值的个数
思路
暴力找规律
#include <set>
#include <iostream>
using namespace std;
int main(){
for (int a = 1; a < 1000; ++a) {
set<int> s;
for (int b = 1; b <= a + 10; b++) {
s.insert(a % b);
}
cout << s.size() << ' ';
}
}
输出为
2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 10 10 11 11 12 12 ...
事实上,对于正整数 a a a, a m o d b a \bmod b amodb的不同取值的个数为
⌊ a − 1 2 ⌋ + 2 \lfloor\frac{a-1}{2}\rfloor+2 ⌊2a−1⌋+2
- 当 a < b a<b a<b 时, a m o d b = a a \bmod b=a amodb=a,其它情况, a m o d b ⩽ ⌊ a − 1 2 ⌋ a \bmod b\leqslant \lfloor\frac{a-1}{2}\rfloor amodb⩽⌊2a−1⌋。
- [ 0 , ⌊ a − 1 2 ⌋ ] [0,\lfloor\frac{a-1}{2}\rfloor] [0,⌊2a−1⌋] 中的所有整数 a m o d b a \bmod b amodb 都可以取到,对于任意的 k ∈ [ 0 , ⌊ a − 1 2 ⌋ ] k\in[0,\lfloor\frac{a-1}{2}\rfloor] k∈[0,⌊2a−1⌋], a m o d ( a − k ) = k a \bmod (a-k)=k amod(a−k)=k 。
代码
#include <iostream>
using namespace std;
int main() {
long long a;
while (cin>>a){
cout<<(a-1)/2+2<<'\n';
}
}