LOJ6682 梦中的数论

题目

不难发现我们要求的东西是\(\sum_{i=1}^n\binom{\sigma(i)}{2}=\sum_{i=1}^n\frac{\sigma(i)(\sigma(i)-1)}{2}=\frac{\sum_{i=1}^n\sigma^2(i)-\sum_{i=1}^n\sigma(i)}{2}\)

\(f(i)=\sigma^2(i)\),不难发现这还是一个积性函数,显然的\(f(p^c)=(c+1)^2\),于是直接大力min_25即可,所以其实就是来复习一下板子

那个\(\sum_{i=1}^n\sigma(i)\)显然可以直接整除分块(但是我太傻了,只会暴力min_25

代码

#include
#define re register
#define LL long long
const int mod=998244353;
inline int dqm(int x) {return x<0?x+mod:x;}
inline int qm(int x) {return x>=mod?x-mod:x;}
LL n,w[200005];int ans;
int p[200005],is[200005],id1[200005],id2[200005],g[200005],Sqr,m;
int S1(LL x,int y) {
    if(x<=1||p[y]>x) return 0;
    int nw=(x<=Sqr?g[id1[x]]:g[id2[n/x]]);nw=dqm(nw-y+1);
    nw=4ll*nw%mod;
    for(re int i=y;i<=p[0]&&1ll*p[i]*p[i]<=x;++i) {
        LL t=p[i];
        for(re int e=1;t<=x;++e,t=1ll*t*p[i])
            nw=qm(nw+1ll*(e+1)*(e+1)%mod*(S1(x/t,i+1)+(e>1))%mod);
    }
    return nw;
}
int main() {
    scanf("%lld",&n);Sqr=sqrt(n)+1;
    for(re int i=2;i<=Sqr;i++) {
        if(!is[i]) p[++p[0]]=i;
        for(re int j=1;j<=p[0]&&p[j]*i<=Sqr;++j) {
            is[p[j]*i]=1;if(i%p[j]==0) break;
        }
    }
    for(re LL l=1,r;l<=n;l=r+1) {
        r=n/(n/l);w[++m]=n/l;
        if(w[m]<=Sqr) id1[w[m]]=m;
        else id2[n/w[m]]=m;
        g[m]=(w[m]-1)%mod;
        ans=qm(ans+1ll*(r-l+1)%mod*(n/l)%mod);
    }
    for(re int j=1;j<=p[0];++j)
        for(re int i=1;i<=m&&p[j]<=w[i]/p[j];++i) {
            int k=(w[i]/p[j]<=Sqr?id1[w[i]/p[j]]:id2[n/(w[i]/p[j])]);
            g[i]=dqm(g[i]-g[k]);g[i]=qm(g[i]+j-1);
        }
    printf("%d\n",1ll*dqm(S1(n,1)-ans+1)*((mod+1)/2)%mod);
    return 0;
}

你可能感兴趣的:(LOJ6682 梦中的数论)