http://www.lydsy.com/JudgeOnline/problem.php?id=1257
topic
Enter n, k and ask for \ [\ sum_ {i = 1} ^ nk \ bmod i \]
$1\leqslant n,k\leqslant 10^9$
answer
This is a topic of neerc2005
If it is directly counted as definitely overtime
$ k \ bmod i $ can be written as
\[k-\left\lfloor \frac{k}{i}\right\rfloor\times i\]
Playing watch will find that $ \ left \ lfloor \ frac {k} {i} \ right \ rfloor $ will sometimes be repeated
Then when is the construction repeated
Need to use
\[\left\lfloor\frac{k}{i}\right\rfloor\leqslant \left(\frac{k}{i}\right)\]
Then
\[\left\lfloor\frac{k}{\left\lfloor\frac{k}{\left\lfloor\frac{k}{i}\right\rfloor}\right\rfloor}\right\rfloor\leqslant\left\lfloor\frac{k}{\left\lfloor\frac{k}{\left(\frac{k}{i}\right)}\right\rfloor}\right\rfloor=\left\lfloor\frac{k}{\left\lfloor i\right\rfloor}\right\rfloor=\left\lfloor\frac{k}{i}\right\rfloor\]
\[\left\lfloor\frac{k}{\left\lfloor\frac{k}{\left\lfloor\frac{k}{i}\right\rfloor}\right\rfloor}\right\rfloor\geqslant\left\lfloor\frac{k}{\left(\frac{k}{\left\lfloor\frac{k}{i}\right\rfloor}\right)}\right\rfloor=\left\lfloor\left\lfloor\frac{k}{i}\right\rfloor\right\rfloor=\left\lfloor\frac{k}{i}\right\rfloor\]
and so
\[\left\lfloor\frac{k}{\left\lfloor\frac{k}{\left\lfloor\frac{k}{i}\right\rfloor}\right\rfloor}\right\rfloor=\left\lfloor\frac{k}{i}\right\rfloor\]
Obviously the middle part should also be equal, because if $ x <y $, then
\[\left\lfloor x\right\rfloor\leqslant\left\lfloor y\right\rfloor\]
This can speed up a part, but how much can it be accelerated?
Direct table verification:
int main() { ll i=1; int cnt=0; while(i<int(1e9)) { cnt++; printf("%10lld", i); i=int(1e9)/i; i=int(1e9)/i; i++; } printf("\n%d\n", cnt); }
Get the worst case only 63244 cycles
Then, you can sum directly
\[\sum_{i=1}^n k\bmod i=nk-\sum_{i=1}^n \left\lfloor\frac{k}{i}\right\rfloor\times i\]
For each segment is equal, the second term is an arithmetic sequence, which can be over the time limit
Although it will not prove the time complexity, but it can save a lot of time for proof
AC code
#include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #define REP(i,a,b) for(int i=(a); i<(b); i++) #define REPE(i,a,b) for(int i=(a); i<=(b); i++) #define PERE(i,a,b) for(int i=(a); i>=(b); i--) using namespace std; typedef long long ll; int main() { int n,k; scanf("%d%d", &n, &k); ll i=1, ans=(ll)n*k; while(i<=n) { if(i>k) { break; } else { int j=k/(k/i); if(j>n) j=n; ans-=(i+j)*(k/i)*(j-i+1)/2; i=j+1; } } printf("%lld\n", ans); }