zoukankan      html  css  js  c++  java
  • Luogu P3708 koishi的数学题

    题意

    给定整数 (n),设 (f(x)=sumlimits_{i=1}^{n}xmod i),对于 (1leq ileq n)(f(i))

    ( exttt{Data Range:}1leq nleq 10^6)

    题解

    做完这题之后看了一下题解区,都写的啥啊,来写篇思路清晰点的。

    考虑推下式子:

    [sumlimits_{i=0}^{n}xmod i=nx-sumlimits_{i=1}^{n}ileftlfloorfrac{x}{i} ight floor ]

    接下来考虑差分:

    [sumlimits_{i=1}^{n}ileft(leftlfloorfrac{x}{i} ight floor-leftlfloorfrac{x-1}{i} ight floor ight)=sumlimits_{i=1}^{n}i[imid x]=sigma(x) ]

    所以

    [sumlimits_{i=0}^{n}xmod i=nx-sumlimits_{i=1}^{x}sigma(i) ]

    线性筛出 (sigma(i)) 的前缀和即可。

    代码

    #include<bits/stdc++.h>
    using namespace std;
    typedef int ll;
    typedef long long int li;
    const ll MAXN=1e6+51;
    ll n,ptot;
    li cur;
    ll np[MAXN],prime[MAXN],low[MAXN];
    li sum[MAXN],sigma[MAXN];
    inline ll read()
    {
        register ll num=0,neg=1;
        register char ch=getchar();
        while(!isdigit(ch)&&ch!='-')
        {
            ch=getchar();
        }
        if(ch=='-')
        {
            neg=-1;
            ch=getchar();
        }
        while(isdigit(ch))
        {
            num=(num<<3)+(num<<1)+(ch-'0');
            ch=getchar();
        }
        return num*neg;
    }
    inline void sieve(ll limit)
    {
        np[1]=low[1]=sum[1]=sigma[1]=1;
        for(register int i=2;i<=limit;i++)
        {
            if(!np[i])
            {
                prime[++ptot]=i,low[i]=i,sum[i]=sigma[i]=i+1;
            }
            for(register int j=1;i*prime[j]<=limit;j++)
            {
                np[i*prime[j]]=1;
                if(i%prime[j]==0)
                {
                    low[i*prime[j]]=low[i]*prime[j];
                    sum[i*prime[j]]=sum[i]+low[i*prime[j]];
                    sigma[i*prime[j]]=sigma[i]/sum[i]*sum[i*prime[j]];
                    break;
                }
                low[i*prime[j]]=prime[j],sum[i*prime[j]]=prime[j]+1;
                sigma[i*prime[j]]=sigma[i]*sigma[prime[j]];
            }
        }
    }
    int main()
    {
        sieve(n=read());
        for(register int i=1;i<=n;i++)
        {
            cur+=sigma[i],printf("%lld ",(li)i*n-cur);
        }
    }
    
  • 相关阅读:
    【缓慢的自学ing】 自己写一个《Minecraft》记录
    Unity随笔3:按钮的"导航"功能
    【随随随随笔】一些STL的糖
    【算法氵】筛法
    【纯感慨】好吃的蒟蒻
    【随随随随笔】OJ错题记录
    【纯感慨】最不擅长的就是配置软件
    【C++Primer笔记】顶层const、常量指针
    hdu 2475 动态树
    hdu 1281 棋盘游戏 网络流
  • 原文地址:https://www.cnblogs.com/Karry5307/p/13678532.html
Copyright © 2011-2022 走看看