/
HDU6706.cpp
68 lines (63 loc) · 1.24 KB
/
HDU6706.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
//ans = 1/2 \sum_{i=1}^n i*phi(i)
#include <bits/stdc++.h>
#define MAXN 1000010
using namespace std;
const int mx=1e6;
const long long M=1e9+7;
const long long inv2=(M+1)>>1;
const long long inv3=(M+1)/3;
const long long inv6=inv2*inv3%M;
int T,n,a,b;
long long prime[MAXN],tot,phi[MAXN];
bool not_prime[MAXN];
map<int,long long> mp;
inline void LinearShaker(int n)
{
phi[1] = 1LL;
for (int i = 2; i <= n; i++)
{
if (!not_prime[i])
{
prime[++tot] = i;
phi[i] = i - 1;
}
for (int j = 1; i * prime[j] <= n; j++)
{
not_prime[i * prime[j]] = true;
if (!(i % prime[j]))
{
phi[i * prime[j]] = phi[i] * prime[j] % M;
break;
}
phi[i * prime[j]] = 1LL * phi[i] * (prime[j] - 1) % M;
}
}
for(long long i=1;i<=n;i++) phi[i]=(phi[i-1]+1LL*phi[i]*i%M)%M;
return ;
}
long long Work(long long n)
{
if (n<mx) return phi[n];
if (mp[n]) return mp[n];
long long ans1=n*(n+1)%M*(n<<1|1)%M*inv6%M,ans=0;
for (long long i=2,j;i<=n;i=j+1)
{
j=n/(n/i);
long long sumi=((i+j)*(j-i+1)/2)%M;
ans=(ans+Work(n/i)%M*sumi)%M;
}
ans=(ans1-ans+M)%M;
return mp[n]=ans;
}
int main()
{
LinearShaker(mx);
scanf("%d",&T);
while (T--)
{
mp.clear();
scanf("%d %d %d",&n,&a,&b);
printf("%lld\n",(Work(n)-1+M)%M*inv2%M);
}
return 0;
}