[CQOI2007]余数求和
Posted zhou2003
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[CQOI2007]余数求和相关的知识,希望对你有一定的参考价值。
题目链接:[CQOI2007]余数求和
题意:求$sum_{i=1}^{n}k mod i$
式子的变形比较常规
$$sum_{i=1}^{n}k mod i=sum_{i=1}^{n}{(k-lfloor{frac{k}{i}}
floor *i)}=k*n-sum_{i=1}^n{lfloor{frac{k}{i}
floor}*i}$$
注意到$lfloor{frac{k}{i}
floor}$的取值程阶梯状递增,一共有$sqrt{n}$种取值可以使用
所以如果我们能将所有$lfloor frac{k}{i}
floor$相同的数一起处理的话,时间复杂度就约为$O(sqrt n)$,可以承受
那么问题就是如何找到这些相同的数了,很明显它们会处在一段区间中
所以只要找到区间的两个端点就可以了
即找到能使$lfloorfrac{k}{i}
floor==lfloorfrac{k}{j}
floor$成立的最大的$j$
打表发现$j=lfloorfrac{k}{lfloor{frac{k}{i}
floor}}
floor$
那么考虑如何证明它
先证明当$j=lfloorfrac{k}{lfloor{frac{k}{i}
floor}}
floor$时结论成立
$ecause lfloorfrac{k}{i}
floor leq frac{k}{i}$
$ herefore frac{n}{lfloor{frac{k}{i}}
floor}geq frac{k}{frac{k}{i}}=k$
即$ herefore frac{n}{lfloor{frac{k}{i}}
floor}geq k$
接下来证明,当$j=lfloorfrac{k}{lfloor{frac{k}{i}
floor}+1}
floor$时结论不成立,即证明$lfloorfrac{k}{lfloor{frac{k}{i}
floor}+1}
floor<a$(记$a=lfloorfrac{k}{i}
floor$)
由待证不等式知$frac{k}{lfloor{frac{k}{i}
floor}+1}<a$
$a*{lfloorfrac{k}{i}
floor}+a>k$
对$k$进行带余除法可得$k=qa+r(0leq r<a)$
$a*{lfloorfrac{k}{i}
floor}+a=a*q+a>qa+r=k$
结论得证
那么接下来只要对$t=lfloorfrac{k}{i}
floor$分类讨论即可
1)若$t
ot=0$,则右边界$r=min(lfloorfrac{k}{t}
floor,n)$(有可能出现$lfloorfrac{k}{t}
floor>n$的情况,比如k很大,这时候不要超出边界)
2)若$t=0$,则右边界$r=n$(此时后面的所有数必然可以保证都>k,那么说明后面的所有数都属于同一部分)
代码
1 #include<iostream> 2 #include<string> 3 #include<string.h> 4 #include<stdio.h> 5 #include<algorithm> 6 using namespace std; 7 int main() 8 { 9 long long n,k; 10 scanf("%lld%lld",&n,&k); 11 long long ans=n*k,l=1,r; 12 while (l<=n) 13 { 14 if (k/l==0) r=n; else r=min(n,k/(k/l)); 15 ans-=(k/l)*(l+r)*(r-l+1)/2; 16 l=r+1; 17 } 18 printf("%lld",ans); 19 return 0; 20 } 21
以上是关于[CQOI2007]余数求和的主要内容,如果未能解决你的问题,请参考以下文章