This is a codeforces question, where we have to calculate the sum of $N\bmod i$ modulo $10^9 + 7$ where $i$ goes from $1$ to $M$.
$N$ and $M$ are very large values about $10^{13}$.
They have provided an editorial for this question, but I dont understand it completely.
I understand why they rewrote the question like this $$mn - \sum_{n=1}^{\min(n,m)} \left \lfloor{\frac{n}{i}}\right \rfloor i$$
I also understand the inequality they wrote ( which was obtained from the fact that factors of a number are less than or equal to its square root since floor(n/i) is a factor of n) $$ \left \lfloor{\frac{n}{i}}\right \rfloor <= (n)^{1/2} $$ But I dont understand anything that they did further, what are the two sums the are talking about and how did the reduce the summation? Any help is appreciated :)
Answer
A very similar problem is present on spoj: SUMPRO
C++ implementation to find the summation of i*(n/i) from i=1 to n for t number of testcases is given below:
#include
#include
using namespace std;
int main()
{
long long t,n,sqrt_n;
long long mod = 1000000007;
cin>>t;
while(t--){
cin>>n;
sqrt_n = sqrt(n);
long long sum = 0;
//finding summation of N/i *i from i=1 to sqrt(N)
for(long long i=1; i<=sqrt_n; i++)
sum = sum + (n/i)*i;
// after i=sqrt(N), there is no need to iterate further bcoz value of N/i will either decrease by 1 or remain same
for(long long i=n/sqrt_n-1; i>=1; i--)
{
long long lower_limit = n/(i+1);
long long upper_limit = n/i;
long long tmp = ((upper_limit*(upper_limit+1))/2 - (lower_limit*(lower_limit+1))/2);
sum = sum + tmp*i;
}
cout<
}
return 0;
}
Complexity of this solution is O(sqrt(N)) for each testcase. If you wanna print the actual sum, don't perform the modulo operation in cout<
No comments:
Post a Comment