题目
传送门
思路
考场上的思路和正解差远了,属实是反演学魔怔了。
首先,对于所有的 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 longusing 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();}
}