ZOJ3558 How Many Sets III(公式题)

转载请注明出处: 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:

 

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 }

 

posted on 2015-08-16 01:21  xyiyy  阅读(234)  评论(0编辑  收藏  举报

导航