观察书中的代码:
for ( int x = 1, gx; x <= n; x = gx+1 ){
gx = k/x ? min ( k/(k/x), n ) : n;
ans -= (k/x) * (x+gx) * (gx-x+1) / 2;
}
gx 的更新为什么要写成这样呢?
gx = k/x ? min ( k/(k/x), n ) : n;
是因为如果 k/x 为0(即x>k)的话,之后都不会更新答案了,所以要 break ,输出答案。上面的写法和下面的写法的结果是一样的:
for ( ULL l = 1;; ){
ULL r;
if ( k < l ) break;
else r = min ( n, k/(k/l) );
ans -= (k/l) * (l+r) * (r-l+1) / 2;
l = r+1; if ( l > n ) break;
}