这是一道比较基础的数论题。
给出一个整数 nnn,计算 ∑i=1n∑j=1nμ(gcd(i,j))sum_{i=1}^n sum_{j=1}^n mu(gcd(i,j))∑i=1n∑j=1nμ(gcd(i,j))。
其中 gcd(i,j)gcd(i,j)gcd(i,j) 表示 i,ji,ji,j 的最大公约数,μ(i)mu(i)μ(i) 表示莫比乌斯函数,它的一个等价定义是 μ(1)=1mu(1)=1μ(1)=1,μ(n)=−∑d<n,d∣nμ(d)mu(n) = - sum_{d<n,d|n} mu(d) μ(n)=−∑d<n,d∣nμ(d) 当 n>1n > 1n>1 时。
输入描述
输入一行包含一个整数 n(1≤n≤107)n(1 leq n leq 10^7)n(1≤n≤107)。
输出描述
输出一行一个整数,表示答案。答案可能很大,请对 998244353998244353998244353 取模后输出。
样例输入 1
5
样例输出 1
14
样例输入 2
100
样例输出 2
3631
这题尼玛,推到自闭。
最后推成:
sig(d,1-n) sig(D/d) mu(D)*mu(d/D)*((n/d))^2
然后中间的sig(D/d) mu(D)*mu(d/D) 是一个卷积,
把他在卷上 1, mu卷mu 卷1 就成了mu
然后度角晒的时候式子里有sig mu(i)
也就是说这里还是得用度角晒 ,就是度角晒套度角晒。。。。。。。(醉了)
然后就是sig(D/d) mu(D)*mu(d/D)不知道怎么线性筛n^(2/3),导致了复杂度的瓶颈卡在了这里
只能过1e9的数据。。。。
也就是说div1过不了。。。
1 #include<bits/stdc++.h>
2 #include<unordered_map>
3 #define N 10000010
4 using namespace std;
5 #define ll long long
6 const ll mod = 998244353;
7
8
9 template<typename T>inline void read(T &x)
10 {
11 x=0;
12 static int p;p=1;
13 static char c;c=getchar();
14 while(!isdigit(c)){if(c=='-')p=-1;c=getchar();}
15 while(isdigit(c)) {x=(x<<1)+(x<<3)+(c-48);c=getchar();}
16 x*=p;
17 }
18 bool vis[N];
19 int mu[N],sum1[N],phi[N];
20 long long sum2[N];
21 int cnt,prim[N];
22 ll Mu[N];
23 ll sum3[N];
24
25 #define NN 10000
26
27 unordered_map<long long,long long>w1;
28 unordered_map<ll,ll>w;
29 unordered_map<long ,long >mumu;
30
31 void get(int maxn)
32 {
33 phi[1]=mu[1]=1;
34 for(int i=2;i<=maxn;i++)
35 {
36 if(!vis[i])
37 {
38 prim[++cnt]=i;
39 mu[i]=-1;phi[i]=i-1;
40 }
41 for(int j=1;j<=cnt&&prim[j]*i<=maxn;j++)
42 {
43 vis[i*prim[j]]=1;
44 if(i%prim[j]==0)
45 {
46 phi[i*prim[j]]=phi[i]*prim[j];
47 break;
48 }
49 else mu[i*prim[j]]=-mu[i],phi[i*prim[j]]=phi[i]*(prim[j]-1);
50 }
51 }
52 for(int i=1;i<=maxn;i++)sum1[i]=sum1[i-1]+mu[i],sum2[i]=sum2[i-1]+phi[i];
53 // 预处理n的
54
55 for(int i=1;i<=NN;i++)
56 {
57 for(int j=1;j<=i;j++) if(i%j == 0) Mu[i] += mu[j]*mu[i/j];
58 }
59 for(int i=1;i<=NN;i++) sum3[i] = sum3[i-1] + Mu[i];
60
61
62
63
64
65 }
66
67 ll djsmu(ll x)
68 {
69 if(x<=10000000)return sum1[x];
70 // if(x == 1) return 1;
71 if(w[x])return w[x];
72 int ans=1;
73
74 for(ll l=2,r;l<=x;l=r+1)
75 {
76 r=x/(x/l);
77 ans-=(r-l+1)*djsmu(x/l);
78 }
79
80 return w[x]=ans;
81 }
82
83 long long djsphi(long long x)
84 {
85 if(x<=10000000)return sum2[x];
86 if(w1[x])return w1[x];
87 long long ans=x*(x+1)/2;
88 for(long long l=2,r;l<=x;l=r+1)
89 {
90 r=x/(x/l);
91 ans-=(r-l+1)*djsphi(x/l);
92 }
93 return w1[x]=ans;
94 }
95
96 ll F(ll n)
97 {
98 if(n==1)return 1;
99 if(n<=NN)return sum3[n];
100 // cout<<n<<endl;
101 if(mumu[n])return mumu[n];
102 ll ans=djsmu(n)*1ll;
103 ll l,r;
104 for(l=2;l<=n;l=r+1)
105 {
106 r=n/(n/l);
107 // cout<<l<<" "<<r<<" "<<n<<endl;
108 ans -= 1ll*(r-l+1)*F(n/l);
109 }
110 mumu[n] = ans;
111 return ans;
112
113 }
114
115 void solve(ll n)
116 {
117 ll l,r; ll ans=0;
118 for(l=1;l<=n;l=r+1)
119 {
120 r=n/(n/l);
121 //cout<<l<<" "<<r<<" "<<n<<endl;
122 ans += (F(r)-F(l-1))%mod*((n/l)*(n/l))%mod;
123 ans %= mod;
124 }
125 ans%=mod ;ans+=mod; ans%=mod;
126 cout<<ans;
127 }
128 // 10000000000
129 int main()
130 {
131 // printf("%f , ",pow(1e10,0.75));
132 // printf("%f ",pow(1e10,0.666));
133 get(10000000);
134 // puts("***");
135 // cout<<F(1e10);
136 //cout<<pow(1e9,0.66666);
137 ll n;cin>>n;
138 solve(n);
139
140 //
141 // int t,n;
142 // read(t);
143 //
144 // while(t--)
145 // {
146 // read(n);
147 // printf("%lld %d
",djsphi(n),djsmu(n));
148 // }
149 // return 0;
150 // return 0;
151 }