将原来所有的的i按照d/i上取整=k的划分为各个区间[next,now),这区间里的ans值就等于(now-next)*k
初始now=n+1,k=1,然后每次next就等于d/i,k依次递增,实际上,不是每一个k的next和now所指代的区间都有意义,即next<now,所以,每当遇到一个这种没有意义的next和now时,就通过d/(now-1)上取整找到新的k,这样就可以大大节省时间。
View Code
1 #include<cstdio> 2 #include<cstring> 3 #include<cmath> 4 #include<algorithm> 5 using namespace std; 6 int main() 7 { 8 long long d,n; 9 while(scanf("%lld%lld",&d,&n)) 10 { 11 if(n==0&&d==0) 12 break; 13 long long ans=0; 14 long long now=n+1,k=1,next; 15 while(now>1) 16 { 17 next=d/k+(d%k!=0); 18 if(now<=next) 19 { 20 next=now-1; 21 k=d/next+(d%next!=0); 22 } 23 else 24 ans+=(now-next)*k,k++,now=next; 25 } 26 printf("%lld\n",ans); 27 } 28 return 0; 29 }