您的位置:首页 > 其它

BZOJ4176 Lucas的数论

2017-05-09 18:30 411 查看

4176: Lucas的数论

Time Limit: 30 Sec Memory Limit: 256 MB

Description

去年的Lucas非常喜欢数论题,但是一年以后的Lucas却不那么喜欢了。

在整理以前的试题时,发现了这样一道题目“求Sigma(f(i)),其中1<=i<=N”,其中 表示i的约数个数。他现在长大了,题目也变难了。
求如下表达式的值:

#include<bits/stdc++.h>
using namespace std;
template <class _T> inline void read(_T &_x) {
int _t; bool flag = false;
while ((_t = getchar()) != '-' && (_t < '0' || _t > '9')) ;
if (_t == '-') _t = getchar(), flag = true; _x = _t - '0';
while ((_t = getchar()) >= '0' && _t <= '9') _x = _x * 10 + _t - '0';
if (flag) _x = -_x;
}
typedef long long LL;
const int maxn = 2e6;
const int mod = 1000000007;
int mu[maxn], prime[maxn], pcnt;
bool vis[maxn];
inline int mul(int a, int b) {return (int)((LL)a * b % mod); }
inline void add(int &a, int b) {a += b; if (a < 0) a += mod; if (a >= mod) a -= mod; }
inline void init() {
mu[0] = 0, mu[1] = 1;
for (register int i = 2; i < maxn; ++i) {
if (!vis[i]) {
prime[++pcnt] = i;
mu[i] = -1;
}
for (register int j = 1, tmp; j <= pcnt && (tmp = prime[j] * i) < maxn; ++j) {
vis[tmp] = true;
if (i % prime[j] == 0) {
mu[tmp] = 0;
break;
}
mu[tmp] = -mu[i];
}
}
for (register int i = 2; i < maxn; ++i) mu[i] += mu[i - 1];
}
map<int, int> Mmu;
int Mu(int n) {
if (n < maxn) return mu
;
if (Mmu.find(n) != Mmu.end()) return Mmu
;
int ret = 1;
for (int i = 2, j, t; i <= n; i = j + 1) {
t = n / i, j = n / t;
add(ret, -mul(Mu(t), j - i + 1));
}
Mmu
= ret;
return ret;
}
inline int F_2(int n) {
int ret = 0;
for (register int i = 1, j, t; i <= n; i = j + 1) {
t = n / i, j = n / t;
add(ret, mul(t, (j - i + 1)));
}
return mul(ret, ret);
}
inline int calc(int n) {
int ret = 0;
for (int i = 1, j, t; i <= n; i = j + 1) {
t = n / i, j = n / t;
add(ret, mul(Mu(j) - Mu(i - 1), F_2(t)));
}
return ret;
}
int main() {
//freopen(".in", "r", stdin);
//freopen(".out", "w", stdout);
init();
int n; read(n);
cout << calc(n) << endl;
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: