题目
思路
考场上的思路和正解差远了,属实是反演学魔怔了。
首先,对于所有的 x x x,它可以通过 2 x 2x 2x 和 2 2 2 连通,而 2 2 2 又可以和所有 m i n p ≤ ⌊ n 2 ⌋ minp\leq \left\lfloor\frac{n}{2}\right\rfloor minp≤⌊2n⌋ 的数连通。所以只有 p > ⌊ n 2 ⌋ p>\left\lfloor\frac{n}{2}\right\rfloor p>⌊2n⌋ 是被孤立的点。
那么,答案就可以转换成
∑
u
=
2
n
−
1
∑
v
=
u
+
1
n
[
m
i
n
p
(
u
)
<
⌊
n
2
⌋
&
m
i
n
p
(
v
)
<
⌊
n
2
⌋
]
u
v
=
∑
u
=
2
n
−
1
∑
v
=
u
+
1
n
u
v
−
∑
p
>
⌊
n
2
⌋
p
(
∑
v
>
p
v
+
∑
u
<
p
u
)
+
∑
p
1
>
⌊
n
2
⌋
p
1
∑
p
2
>
p
1
p
2
=
∑
u
=
2
n
−
1
∑
v
=
u
+
1
n
u
v
−
∑
p
>
⌊
n
2
⌋
p
∑
v
=
2
n
v
+
1
2
(
(
∑
p
>
⌊
n
2
⌋
p
)
2
+
∑
p
>
⌊
n
2
⌋
p
2
)
\sum_{u=2}^{n-1}\sum_{v=u+1}^n[minp(u)<\left\lfloor\frac{n}{2}\right\rfloor \& minp(v)<\left\lfloor\frac{n}{2}\right\rfloor]uv\\ =\sum_{u=2}^{n-1}\sum_{v=u+1}^nuv-\sum_{p>\left\lfloor\frac{n}{2}\right\rfloor}p\left(\sum_{v>p}v+\sum_{u<p}u \right)+\sum_{p_1>\left\lfloor\frac{n}{2}\right\rfloor}p_1\sum_{p_2>p_1}p_2\\ =\sum_{u=2}^{n-1}\sum_{v=u+1}^nuv-\sum_{p>\left\lfloor\frac{n}{2}\right\rfloor}p\sum_{v=2}^nv+\frac{1}{2}\left(\left(\sum_{p>\left\lfloor\frac{n}{2}\right\rfloor}p\right)^2+\sum_{p>\left\lfloor\frac{n}{2}\right\rfloor}p^2\right)
u=2∑n−1v=u+1∑n[minp(u)<⌊2n⌋&minp(v)<⌊2n⌋]uv=u=2∑n−1v=u+1∑nuv−p>⌊2n⌋∑p(v>p∑v+u<p∑u)+p1>⌊2n⌋∑p1p2>p1∑p2=u=2∑n−1v=u+1∑nuv−p>⌊2n⌋∑pv=2∑nv+21
p>⌊2n⌋∑p
2+p>⌊2n⌋∑p2
所以我们只需要用 min25筛 求出质数的和还有平方和就可以啦。用
g
(
n
,
∣
P
∣
)
g(n,|P|)
g(n,∣P∣) 即可。
注意,不要跑两遍,会T。
⌊
n
2
⌋
\left\lfloor\frac{n}{2}\right\rfloor
⌊2n⌋ 是在整除分块中求过的,可以直接用。
代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e6+7,inf=1e18,mod=998244353;
int sqr,n,tot;
vector<int> sp1(N),sp2(N),g1(N),g2(N),w(N),id1(N),id2(N),p;
int power(int x,int t)
{
int b=1;
while(t)
{
if(t&1) b=b*x%mod;
x=x*x%mod; t>>=1;
}
return b;
}
void init(int n)
{
p.push_back(0);
tot=0;
vector<bool> bz(n+1);
for(int i=2; i<=n; i++)
{
if(!bz[i])
{
p.push_back(i);
int now=p.size()-1;
sp1[now]=(sp1[now-1]+i)%mod;
sp2[now]=(sp2[now-1]+i*i%mod)%mod;
}
for(auto j:p)
{
if(!j) continue;
if(i*j>n) break;
bz[i*j]=1;
if(i%j==0) break;
}
}
}
void O_o()
{
cin>>n;
sqr=sqrt(n);
init(sqr);
int inv2=power(2,mod-2),inv3=power(3,mod-2);
for(int i=1,j; i<=n; i=j+1)
{
j=n/(n/i);
w[++tot]=n/i;
int now=w[tot]%mod;
g1[tot]=now*(now+1)/2%mod-1;
g2[tot]=now*(now+1)%mod*(2*now+1)%mod*inv2%mod*inv3%mod-1;
if(w[tot]<=sqr) id1[w[tot]]=tot;
else id2[n/w[tot]]=tot;
}
for(int i=1; i<p.size(); i++)
{
for(int j=1; j<=tot,p[i]*p[i]<=w[j]; j++)
{
int k=w[j]/p[i]<=sqr?id1[w[j]/p[i]]:id2[n/(w[j]/p[i])];
//g(w[j],i) = g(w[j],i-1) - f'(p[i])*(g(w[k],j-1)-sp[i-1])
(g1[j]-=p[i]*(g1[k]-sp1[i-1])%mod)%=mod;
(g2[j]-=p[i]*p[i]%mod*(g2[k]-sp2[i-1])%mod)%=mod;
}
}
int f1=g1[1],f2=g2[1];//g(n,|P|)
int k=n/2<=sqr?id1[n/2]:id2[n/(n/2)];
int h1=g1[k],h2=g2[k];//g(n/2,|P|)
n%=mod;
int ans=inv2*(inv2*(n*n%mod+n)%mod*(n*(n-1)%mod-2)%mod
-inv2*inv2%mod*n%mod*n%mod*(n-1)%mod*(n-1)%mod+2
-inv2*inv3%mod*n%mod*(n-1)%mod*(2*n-1)%mod)%mod;
ans=ans-(n*(n+1)/2%mod-1)*(f1-h1)%mod+((f1-h1)*(f1-h1)%mod-(f2-h2))*inv2%mod+(f2-h2);
ans%=mod;
(ans+=mod)%=mod;
cout<<ans<<"\n";
}
signed main()
{
ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
cout<<fixed<<setprecision(2);
int T=1;
// cin>>T;
while(T--)
{
O_o();
}
}