1 条题解

  • 0
    @ 2025-8-24 22:05:05

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar 南城忆潇湘
    今天又是摸鱼的一天

    搬运于2025-08-24 22:05:05,当前版本为作者最后更新于2018-10-02 08:06:54,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    不得不说,这题目是一道对于noip选手的数论好题,涉及的知识点比较多,算法也都不是很难,但是很具有思考性。
    首先,我们对于每一个i,来枚举~~(打表)出它所对应的值。 然后,我们发现,对于第i-1行,如果它要变成第i行,我们就增加从1/2~1/i-1(也就是逆元之和,用前缀和来维护),然后再减去它的约数,就可以得到这一行的和了qwq(不包括1和它自己,想一想为什么)
    然后递推即可(O(≧口≦)O,我一开始以为有啥数学方法诶)
    话说CYJian的题目怎么这么多离线算法,而且这次比赛这么多筛法
    顺带附上知识点所需的模板:
    同余方程
    乘法逆元
    筛素数(稍微改一改就可以筛约数)
    代码(本人用的是埃氏筛,不知道为啥比标程的欧拉筛还快
    (玄学)~~,不过从1-n的每个数的约数之和接近nlnn吧(也就是说欧拉筛应该是被卡了))

    #include<vector>
    #include<cstdio>
    #include<iostream>
    using namespace std;
    const int N=1000000,p=998244353;
    int inv[N+1],f[N+1],sum[N+1],prime[N+1];
    void pre(){
        inv[1]=1;
        for(int i=2;i<=N;i++)	
            inv[i]=(((long long)-inv[p%i]*(p/i))%p+p)%p;
        for(int i=2;i<=N;i++)
            sum[i]=((long long)sum[i-1]+inv[i])%p;
        for(int i=2;i<=N;i++)
            for(int j=i+i;j<=N;j+=i)
                prime[j]++;//注意,这里的prime指的是j的约数(除了1和它自己)的和,打习惯prime了qwq,大家将就一下
        for(int i=3;i<=N;i++){
            long long cnt=0;
            cnt=(f[i-1]-f[i-2]+p)%p+sum[i-1];
            cnt=(cnt+p-prime[i]+f[i-1])%p;	f[i]=cnt;//f[i]用前缀和的形式表示(后面要用)
        }
        return ;
    }
    int main(){
        int t; pre();
        cin>>t;
        while(t--){
            int a,b;
            scanf("%d%d",&a,&b);
            int ans=(((long long)f[b]-f[a-1])%p+p)%p;
            printf("%d\n",ans);
        }
        return 0;
    }
    
    • 1

    信息

    ID
    3880
    时间
    404ms
    内存
    40MiB
    难度
    6
    标签
    递交数
    0
    已通过
    0
    上传者