Educational Codeforces Round 5 E. Sum of Remainders (思维题)

题目链接: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 }
View Code
原文地址:https://www.cnblogs.com/Recoder/p/5757753.html