转载请注明出处: http://www.cnblogs.com/fraud/ ——by fraud
How Many Sets III
Time Limit: 2 Seconds Memory Limit: 65536 KB
Given a set S = {1, 2, ..., n}, your job is to count how many set T satisfies the following condition:
- T is a subset of S
- Elements in T can form an arithmetic progression in some order.
Input
There are multiple cases, each contains only one integer n ( 1 ≤ n ≤ 109 ) in one line, process to the end of file.
Output
For each case, output an integer in a single line: the total number of set T that meets the requirmentin the description above, for the answer may be too large, just output it mod 100000007.
Sample Input
2 3
Sample Output
1 4
看到这种输出只和一个数有关的,而且还是整数,想都不想,先暴力求出前几项,然后oeis大法,查到公式后
a(n) = sum { i=1..n-1, j=1..floor((n-1)/i) } (n - i*j)
发现这个公式只是n^2的,于是我们需要优化其中的步骤,首先,对于第二维,我们很容易搞掉,那么对于第一维,我们发现其中有一个(n-1)/i,那么其实有很多是对应的,于是我们只需要枚举1到sqrt(n-1)即可。即对于每一个i,在公差在(n-1)/(i+1) + 1到(n-1)/i这个范围内是可求的,另外注意求一下其相对的情况,看上去比较轻松,然而我这种数学渣还是推了半个多小时才推出来的
1 /** 2 * code generated by JHelper 3 * More info: https://github.com/AlexeyDmitriev/JHelper 4 * @author xyiyy @https://github.com/xyiyy 5 */ 6 7 #include <iostream> 8 #include <fstream> 9 10 //##################### 11 //Author:fraud 12 //Blog: http://www.cnblogs.com/fraud/ 13 //##################### 14 //#pragma comment(linker, "/STACK:102400000,102400000") 15 #include <iostream> 16 #include <sstream> 17 #include <ios> 18 #include <iomanip> 19 #include <functional> 20 #include <algorithm> 21 #include <vector> 22 #include <string> 23 #include <list> 24 #include <queue> 25 #include <deque> 26 #include <stack> 27 #include <set> 28 #include <map> 29 #include <cstdio> 30 #include <cstdlib> 31 #include <cmath> 32 #include <cstring> 33 #include <climits> 34 #include <cctype> 35 36 using namespace std; 37 typedef long long ll; 38 39 // 40 // Created by xyiyy on 2015/8/5. 41 // 42 43 #ifndef ICPC_INV_HPP 44 #define ICPC_INV_HPP 45 typedef long long ll; 46 47 void extgcd(ll a, ll b, ll &d, ll &x, ll &y) { 48 if (!b) { 49 d = a; 50 x = 1; 51 y = 0; 52 } 53 else { 54 extgcd(b, a % b, d, y, x); 55 y -= x * (a / b); 56 } 57 } 58 59 ll inv(ll a, ll mod) { 60 ll x, y, d; 61 extgcd(a, mod, d, x, y); 62 return d == 1 ? (x % mod + mod) % mod : -1; 63 } 64 65 66 #endif //ICPC_INV_HPP 67 68 const ll mod = 100000007; 69 70 class TaskJ { 71 public: 72 void solve(std::istream &in, std::ostream &out) { 73 ll n; 74 while (in >> n) { 75 ll ans = 0; 76 ll m = n - 1; 77 ll num = inv(2, mod); 78 for (ll i = 1; i * i <= m; i++) { 79 ll r = m / i; 80 ll l = m / (i + 1) + 1; 81 if (l > r)continue; 82 ans += (n * i % mod * (r - l + 1) % mod - 83 (1LL + i) * i % mod * num % mod * (l + r) % mod * (r - l + 1) % mod * num % mod) % mod + mod; 84 ans %= mod; 85 if (i != r)ans += (n * r % mod - i * r % mod * (1LL + r) % mod * num % mod) % mod + mod; 86 ans %= mod; 87 } 88 out << ans << endl; 89 } 90 } 91 }; 92 93 int main() { 94 std::ios::sync_with_stdio(false); 95 std::cin.tie(0); 96 TaskJ solver; 97 std::istream &in(std::cin); 98 std::ostream &out(std::cout); 99 solver.solve(in, out); 100 return 0; 101 }