题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1257
暴力枚举肯定是不行的,50%还可以
计算k%x时分成两种情况:
1、x>k时显然结果是k
2、x<=k时答案是梯度的,当 x∈[⌊k/(t+1)+1⌋,⌊k/t⌋]时结果是一段公差为t的等差数列,分块处理,每段可以O(1)处理,要处理√n次,[1,√n]这段就不是按规律的了,或者说是每段的长度退化成1,所以可以一个个算过去
综上,这题就可以分段做复杂度是O(2√n)
贴代码
#include<cstdio>
#include<cstring>
using namespace std;
long long kk,n,k,t,ans,x,y,z;
int main(){
freopen("1257.in","r",stdin);
freopen("1257.out","w",stdout);
scanf("%lld%lld",&n,&k);
ans=0;t=2;y=0;
if (n>k)ans=(n-k)*k,n=k;
kk=n;
while (kk!=0){
x=k%kk;
y=k/t+1;
if (y>kk) y=kk;
z=k%y;
if (x<=z)ans+=(z+x)*((z-x)/(t-1)+1)/2;
t++;
kk=y-1;
}
printf("%lld",ans);
return 0;
}
【写的有漏洞的,欢迎路过大神吐槽】
2016/12/30 15:30:14
Ending.