您的位置:首页 > 其它

BZOJ3512 DZY Loves Math IV

2017-05-15 16:54 288 查看

3512: DZY Loves Math IV

Time Limit: 15 Sec Memory Limit: 128 MB

Description

给定n,m,求

#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;
}
using namespace std;
const int mod = 1e9 + 7;
const int N = 1e5 + 10;
const int M = 7e6 + 10;
typedef long long LL;
inline int add(int a, int b) {
a += b;
if (a < 0) a += mod; if (a >= mod) a -= mod;
return a;
}
inline int mul(int a, int b) {
return (int)((LL)a * b % mod);
}
int phi[M], prime[M / 10], pcnt;
int Div
, mx
;
bool vis[M];
inline void init() {
phi[1] = mx[1] = Div[1] = 1;
for (register int i = 2, j, tmp; i < M; ++i) {
if (!vis[i]) {
prime[++pcnt] = i;
phi[i] = i - 1;
if (i < N) Div[i] = 1, mx[i] = i;
}
for (j = 1; j <= pcnt && (LL)prime[j] * i < M; ++j) {
tmp = prime[j] * i;
vis[tmp] = true;
if (tmp < N) mx[tmp] = prime[j];
if (i % prime[j] == 0) {
phi[tmp] = phi[i] * prime[j];
if (tmp < N) Div[tmp] = Div[i] * prime[j];
break;
}
phi[tmp] = phi[i] * (prime[j] - 1);
if (tmp < N) Div[tmp] = Div[i];
}
}
for (register int i = 2; i < M; ++i) phi[i] = add(phi[i], phi[i - 1]);
}
struct Hash_table {
int tot, fir[10000];
struct Edge {
int v, res, nxt;
}e[100000];
Hash_table() {memset(fir, -1, sizeof fir); tot = 0; }
inline void add(int a, int b, int c) {
e[++tot] = (Edge){b, c, fir[a]};
fir[a] = tot;
}
inline int find(int x) {
int w = x >> 20;
for (int u = fir[w]; ~u; u = e[u].nxt)
if (e[u].v == x) return e[u].res;
return -1;
}
inline void insert(int v, int res) {
add(v >> 20, v, res);
}
}mp;
int Phi(int n) {
if (n < M) return phi
;
int w = mp.find(n); if (~w) return w;
int res = (int)(((LL)n * (n + 1) >> 1) % mod);
for (int i = 2, j; i <= n; i = j + 1) {
j = n / (n / i);
res = add(res, -mul(j - i + 1, Phi(n / i)));
}
mp.insert(n, res); return res;
}
int sum(int n, int m) {
if (!m) return 0;
if (m == 1) return phi
- phi[n - 1];
if (n == 1) return Phi(m);
int &k = mx
;
return add(mul(sum(n / k, m), k - 1), sum(n, m / k));
}
int f[100010];
int main() {
//freopen("3512.in", "r", stdin);
//freopen("3512.out", "w", stdout);
init();
int n, m, ans = 0; read(n), read(m);
memset(f, -1, sizeof f);
for (int i = 1; i <= n; ++i) {
int k = Div[i], t = i / k, ret;
if (~f[t]) ret = mul(k, f[t]);
else ret = mul(k, (f[t] = sum(t, m)));
ans = add(ans, ret);
}
cout << ans << endl;
return 0;
}


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