1.杜教筛推到一下即可,就会发现是卷积出来的函数是平方的前缀和,杜教筛的板子拿出来A了。
#include<bits/stdc++.h>
#include<iostream>
#include <cstdio>
#include <map>
#pragma warning(disable:4996)
#define N 1000010
#define mod 6000000042ll
using namespace std;
typedef long long ll;
map<ll, ll> f;
map<ll, ll>::iterator it;
ll m = 1000000, phi[N], prime[N], tot, sum[N];
bool np[N];
ll s1(ll l, ll r)
{
return (l + r) * (r - l + 1) % mod / 2;
}
ll s2(ll x)
{
return x * (x + 1) % mod * (2 * x + 1) % mod / 6;
}
ll query(ll n)
{
if (n <= m) return sum[n];
it = f.find(n);
if (it != f.end()) return it->second;
ll ans = s2(n), i, last;
for (i = 2; i <= n; i = last + 1) last = n / (n / i), ans = (ans - s1(i, last) * query(n / i) % mod + mod) % mod;
f[n] = ans;
return ans;
}
int main()
{
ll i, j, n;
phi[1] = sum[1] = 1;
for (i = 2; i <= m; i++)
{
if (!np[i]) phi[i] = i - 1, prime[++tot] = i;
for (j = 1; j <= tot && i * prime[j] <= m; j++)
{
np[i * prime[j]] = 1;
if (i % prime[j] == 0)
{
phi[i * prime[j]] = phi[i] * prime[j];
break;
}
else phi[i * prime[j]] = phi[i] * (prime[j] - 1);
}
sum[i] = (sum[i - 1] + i * phi[i]) % mod;
}
scanf("%lld", &n);
printf("1 %lld\n", query(n) % 1000000007);
return 0;
}