题目链接:http://codeforces.com/problemset/problem/616/E
题意很简单就不说了。
因为n % x = n - n / x * x
所以答案就等于 n * m - (n/1*1 + n/2*2 ... n/m*m)
在根号n复杂度枚举x,注意一点当m>n时,后面一段加起来就等于0,就不用再枚举了。
中间一段x1 ~ x2 的n/x可能相等,所以相等的一段等差数列求和。
1 //#pragma comment(linker, "/STACK:102400000, 102400000") 2 #include <algorithm> 3 #include <iostream> 4 #include <cstdlib> 5 #include <cstring> 6 #include <cstdio> 7 #include <vector> 8 #include <cmath> 9 #include <ctime> 10 #include <list> 11 #include <set> 12 #include <map> 13 using namespace std; 14 typedef __int64 LL; 15 typedef pair <int, int> P; 16 const int N = 1e5 + 5; 17 vector <LL> myset; //存储x 18 LL mod = 1e9 + 7; 19 20 int main() 21 { 22 LL n, m; 23 scanf("%lld %lld", &n, &m); 24 LL k = min(m, n); 25 myset.push_back(k); 26 for(LL i = 1; i*i <= n; ++i) { 27 myset.push_back(i); 28 if(i * i != n) { 29 myset.push_back(n/i); 30 } 31 } 32 sort(myset.begin(), myset.end()); 33 LL ans = (n%mod)*(m%mod)%mod, cnt = 0; 34 for(LL i = 0; i < myset.size() && myset[i] <= k; ++i) { 35 LL temp = myset[i]; 36 if(cnt) { 37 LL num; 38 if((temp - cnt) % 2) 39 num = ((temp + cnt + 1) / 2 % mod) * ((temp - cnt) % mod) % mod; 40 else 41 num = ((temp - cnt) / 2 % mod) * ((temp + cnt + 1) % mod) % mod; 42 num = ((n / temp) % mod * num) % mod; 43 ans = ((ans - num) % mod + mod) % mod; 44 } 45 else { 46 ans = (ans - n) % mod; 47 } 48 cnt = temp; 49 } 50 printf("%lld ", (ans + mod) % mod); 51 return 0; 52 }