中文题面

这道题就是LightOJ某题的升级版

前段时间我是直接用√k前暴力后分块的处理方式,然后直接套个等差求和

这次看到了dalao的证明再次让我知道我好菜啊

在这里做下笔记,学习一下对于整除运算的分析方法

关于[ki]×i,i[1,n][\frac{k}{i}]×i,i∈[1,n]的处理

x[1,k],g(x)=[k/[k/x]],f(x)=k/xx∈[1,k],g(x)=[k/[k/x]],f(x)=k/x

g(x)=[k/[f(x)]][k/f(x)]=xg(x) = [k/[f(x)]] ≥ [k/f(x)] = x

得到g(x)xg(x) ≥ x,换为底 [k/g(x)][k/x][k/g(x)]≤[k/x]

另一方面[k/g(x)]=[k/[k/[k/x]]][k/k[k/x]]=[k/x][k/g(x)] = [k/[k/[k/x]]] ≥ [k/k*[k/x]] = [k/x]

由①②可知x[1,k]x∈[1,k]时,[k/g(x)]=[k/x][k/g(x)]=[k/x]

既对所有的i[x,g(x)],[k/i]=[k/x]i∈[x,g(x)],[k/i]=[k/x]

既计算的规模取决于ii[k/i][k/i],

iki≤\sqrt{k}时,计算规模为k\sqrt{k}(可认为ii逐一计算)

i>ki>\sqrt{k}时,计算规模为[k/i][k/i]的不同的值,max [k/i] <kmax{\ {[k/i]}\ }<\sqrt{k},规模还是k\sqrt{k}(分段计算)

这也是之前可以暴力分块的依据,实际运算的时候要注意防止越界(n)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main(){
	ll n,k,ans,gx,l,r,w,val;
	while(cin>>n>>k){
		ans=n*k;
		for(int x=1; x<=n; x=gx+1){
			val=k/x;
			if(val==0) break;
			gx=min(k/(k/x),n);
			l=x,r=gx;
			w=r-l+1;
			ans -= val*(l+r)*w/2;
		}
		cout<<ans<<endl;
	}
	return 0;
}