Problem - D - Codeforces 
好玩题。
 
首先考虑如果我们已经知道了 $n$ 的划分这个题应该怎么做。
我们可以考虑枚举每一段的 $\tt gcd$ 不妨设为 $d$,之后考虑进行计算。
$$ \begin{aligned} & \sum_{d = L} ^ {R} \sum_{k = 1} ^ {\lfloor \frac{R}{d} \rfloor} \mu(k) \times\binom{\lfloor \frac{R}{kd} \rfloor}{2} \\ \end{aligned} $$
也就是考虑枚举每一个公约数,之后考虑两个数的公约数是当前的 $\tt gcd$ 的贡献。
当然还要加上每个数自身的贡献。
 
我们既然要考虑其最小值,我们考虑上面这个式子能取到最小值的是尽量让其 $= 0$。
考虑对于一个 $[L, R]$ 只要让后面的组合数等于 $0$ 即可,我们考虑取 $d = L$ 保证限制进行考虑,可以得到 $1 \le k$,那么只需要让 $k = 1, \lfloor \frac{R}{L} \rfloor = 0$ 即可。
显然我们的 $R$ 最大可以取到 $2L - 1$,那么可以得到一个有趣的结论。
我们考虑每次进行划分,区间肯定是 $\times 2$,那么如果 $2 ^ k \ge n$ 显然答案就是 $n$ 了。 
 
但是很显然,这个东西甚至需要枚举划分数,直接去世。
那么对于划分数我们还有一种考虑,就是进行 $\tt Dp$,方程比较显然。
$$ \begin{aligned} f(i, j) = \min { f(i - 1, k) + c(k + 1, j) } \end{aligned} $$
乍一看状态是 $O(n ^ 2)$ 的,复杂度更高。别忘记了我们上面的边界那么我们可以得到 $k$ 是 $O(\log n)$ 级别的。
但是转移复杂度还是 $O(n)$ 呀?
我们考虑将 $c$ 的式子拿出来看看。
$$ \begin{aligned} c(L, R) &= \sum_{i = L} ^ R \sum_{j = i} ^ R [ \gcd(i, j) \ge L ] \\ &= \sum_{d = L} ^ R \sum_{i = L} ^ R \sum_{j = i} ^ R [ \gcd(i, j) == d ] \\ &= \sum_{d = L} ^ R \sum_{i = 1} ^ {\lfloor \frac{R}{d} \rfloor } \sum_{j = i} ^ {\lfloor \frac{R}{d} \rfloor } [ \gcd(i, j) == 1 ]\\ &= \sum_{d = L} ^ R \sum_{j = 1} ^ {\lfloor \frac{R}{d} \rfloor } \sum_{i = 1} ^ j [ \gcd(i, j) == 1 ]\\ &= \sum_{d = L} ^ R \sum_{j = 1} ^ {\lfloor \frac{R}{d} \rfloor } \varphi(j) \\ &= \sum_{d = L} ^ R sum\varphi ( \lfloor \frac{R}{d} \rfloor ) \end{aligned} $$
发现这个东西可以进行整除分块,那么算 $c$ 的复杂度是可以接受的,但是这个东西不能单调队列和斜率优化呀?
我们尝试一下其决策是不是单调的,也就是带入四边形不等式。
$$ \begin{aligned} c(l, r) + c(l + 1, r + 1) \le  c(l + 1, r) + c(l, r + 1) \\ c(l, r) - c(l + 1, r) \le c(l, r + 1) - c(l + 1, r + 1) \end{aligned} $$
显然成立,我们可以进行决策单调性优化。
笔者采用分治的形式,比较好些。
 
代码的时候注意边界的细节,特别是预处理 $\tt Dp$ 的时候需要考虑转移区间 $[L, R]$ 与 $\tt mid$ 的关系。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 #include  <bits/stdc++.h>  using  namespace  std;namespace  Legendgod {	namespace  Read { 		#ifdef  Fread  		const  int  Siz = (1  << 21 ) + 5 ; 		char  *iS, *iT, buf[Siz]; 		#define  gc() ( iS == iT ? (iT = (iS = buf) + fread(buf, 1, Siz, stdin), iS == iT ? EOF : *iS ++) : *iS ++ )  		#define  getchar gc  		#endif   		template  <typename  T> 		void  r1 (T &x)   { 		    x = 0 ; 			char  c (getchar())  ; 			int  f (1 )  ; 			for (; !isdigit (c); c = getchar ()) if (c == '-' ) f = -1 ; 			for (; isdigit (c); c = getchar ()) x = (x << 1 ) + (x << 3 ) + (c ^ 48 ); 			x *= f; 		} 		template  <typename  T, typename ...Args> 		void  r1 (T &x, Args&...arg)   { 			r1 (x), r1 (arg...); 		} 		#undef  getchar  	} using  namespace  Read;const  int  maxn = 1e5  + 5 ;constexpr  int  N = 17 ;constexpr  int  M = 1e5 ;#define  int long long int  n, K;int  f[maxn][N + 3 ];int  vis[maxn], pr[maxn], phi[maxn], sp[maxn], tot (0 );void  init (int  x)   {    phi[1 ] = 1 ;     for (int  i = 2 ; i <= x; ++ i) {         if (!vis[i]) pr[++ tot] = i, phi[i] = i - 1 ;         for (int  j = 1 , k; k = i * pr[j], k <= x && j <= tot; ++ j) {             vis[k] = 1 ;             if (!(i % pr[j])) {                 phi[k] = phi[i] * pr[j];                 break ;             }             phi[k] = phi[i] * phi[pr[j]];         }     }     for (int  i = 1 ; i <= x; ++ i) sp[i] = sp[i - 1 ] + phi[i]; } int  C (int  l,int  r)   {    if (l > r) return  0 ;     int  res (0 )  ;     for (int  i = l, last; i <= r; i = last + 1 ) {         last = min (r, r / (r / i));         res += (last - i + 1 ) * sp[r / i];     }     return  res; } void  Gdp (int  l,int  r,int  L,int  R)   {    if (l > r) return  ;     int  mid = (l + r) >> 1 ;     int  sum (C(R + 1 , mid)) , ps (0 ) , mn (0x3f3f3f3f )  ;     for (int  i = min (mid, R); i >= L; -- i) {         sum += sp[mid / i];         int  tmp = sum + f[i - 1 ][K - 1 ];         if (tmp < mn) {             mn = tmp, ps = i;         }     }     f[mid][K] = mn;     Gdp (l, mid - 1 , L, ps), Gdp (mid + 1 , r, ps, R); } void  Solve ()   {    r1 (n, K);     int  x = n, tmp = 0 ;     while (x) ++ tmp, x >>= 1 ;     if (tmp <= K) return  printf ("%lld\n" , n), void ();     printf ("%lld\n" , f[n][K]); } signed  main ()   {	int  i, j, T (1 ); 	init (maxn - 5 );     for (i = 1 ; i <= M; ++ i) f[i][1 ] = C (1 , i);     for (K = 2 ; K <= N; ++ K) Gdp (1 , M, 1 , M);     r1 (T);     while (T --) Solve (); 	return  0 ; } } signed  main ()   { return  Legendgod::main (), 0 ; }