[18/8]+[18/9]+[18/10]=3+2+2=7
[x]为实数x向上取整的值,例如 [5]=[4.03]=[4.92]=5
1 #include<iostream>
2 #include<cmath>
3 #include<cstdio>
4 using namespace std;
5 long long a,b,ans;
6 double c;
7 long long f(double n,long long a,long long b )
8 {
9 if(ceil(n/a)==ceil(n/b)) return (b-a+1)*(ceil(n/a));
10 long long mid=(a+b)/2;
11 return f(n,a,mid)+f(n,mid+1,b);
12 // return ans;
13 }
14 int main()
15 {
16 scanf("%lf%lld%lld",&c,&a,&b);
17 printf("%lld",f(c,a,b));
18 return 0;
19 }
思路:分治的思想,如果 f(n, a, b) 表示该题的解,那么一定有 f(n, a, b) = f(n, a, (a + b) / 2) + f(n, (a + b) / 2 + 1, b);容易知道:当 [n / a] = [n / b] 时,f(n, a, b) = (b - a + 1) * [n / a],这比求和快一点。可知在b远大于n时,许多加数都为1。如 n = 5, b = 16, a = 4 时,可以用式 (2 + 1 * 6) + (1 * 6) 得解。但在n大于b时,对于任意 i 属于 [a, b],[n / i] > 1。因此,最差情况时,该算法时间复杂度不如朴素算法。如果一次除法并且向上取整的时间复杂度为O(1),那么该算法的时间复杂度为O(b-a)。暴力啥的那都弱爆了
反思:二分并不一定要分到1