这道题初看确实没什么思路,感觉之前的数论知识都用不上,只好自己找规律
首先当n>=k 这部分是很容易直接算出的
下面我们先来尝试这穷举i,
不难发现当穷举i时,总存在一段连续的除数,k div i=p定值
设这段是i~j,则这部分的的余数和signma(k-p*q) (i<=q<=j) 即为k*(j-i+1)-p*(i+j)*(j-i+1)/2
由于随着i的增大,k div i逐渐变小,是接近单调的
因此这样一段连续的除数我们可以通过二分确定其范围
这样就可以AC了

 1 var ans:int64;
 2     n,k,i,j,p:longint;
 3 
 4 function find(l,r:longint):longint;
 5   var m,w:longint;
 6   begin
 7     w:=l;
 8     while l<=r do
 9     begin
10       m:=(l+r) shr 1;
11       if (k div m=p) then
12       begin
13         w:=m;
14         l:=m+1;
15       end
16       else r:=m-1;
17     end;
18     exit(w);
19   end;
20 
21 begin
22   readln(n,k);
23   if n>k then
24   begin
25     ans:=ans+int64(n-k)*int64(k);
26     n:=k-1;
27   end;
28   if n=k then dec(n);
29   i:=1;
30   while i<=n do
31   begin
32     p:=k div i;
33     j:=find(i,n);
34     ans:=ans-int64(j-i+1)*int64(i+j)*int64(p) div 2;
35     i:=j+1;
36   end;
37   ans:=ans+int64(n)*int64(k);
38   writeln(ans);
39 end.
40 
41  
View Code

 

posted on 2014-10-16 22:49  acphile  阅读(195)  评论(0编辑  收藏  举报