【JZOJ5250】【GDOI2018模拟8.11】质数

本文详细解析了一道涉及数论的复杂算法问题,通过巧妙转换将原问题转化为求解特定数学表达式的值,并最终通过分块计算的方式给出了高效的求解方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Description

这里写图片描述

Data Constraint

这里写图片描述

Solution

我们发现2f(n)就等于i|n[gcd(i,n/i)==1]
所以题目就是求:

i=1nj|i[gcd(j,i/j)==1]
=j=1ni=1n/j[gcd(i,j)==1]

=j=1ni=1n/jd|gcd(i,j)μ(d)

=d=1nμ(d)k=1n/dn/d2k

枚举d,然后分块计算后面即可。

Code

#include<iostream>
#include<cmath>
#include<cstring>
#include<cstdio>
#include<algorithm>
#define ll long long
using namespace std;
const ll maxn=1e6+5,mo=998244353; 
ll bz[maxn],u[maxn],n,i,t,j,k,l,x,y,z,d[maxn],ans,p[maxn];
ll dg(ll n){
    ll t,i=1,x=0;
    while (i<=n){
        t=n/(n/i);
        x=x+n/i*(t-i+1)%mo;i=t+1;
    }
    return x%mo;
}
int main(){
//  freopen("data.in","r",stdin);
    scanf("%lld",&n);u[1]=1;t=sqrt(n);
    for (i=2;i<=t;i++){
        if (!bz[i]) bz[i]=1,d[++d[0]]=i,u[i]=-1;
        for (j=1;j<=d[0];j++){
            if (i*d[j]>t) break;
            u[i*d[j]]=-u[i];bz[i*d[j]]=1;
            if (i%d[j]==0){
                u[i*d[j]]=0;
                break;
            }
        }
    }
    for (i=1;i<=t;i++)
        ans=ans+u[i]*dg(n/(i*i));
    ans=(ans%mo+mo)%mo;
    printf("%lld\n",ans);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值