• LOJ 572 「LibreOJ Round #11」Misaka Network 与求和——min_25筛


    题目:https://loj.ac/problem/572

    莫比乌斯反演得 ( ans=sumlimits_{D=1}^{n}leftlfloorfrac{n}{D} ight floor^2sumlimits_{d|D}f(d)^kmu (frac{D}{d}) )

    计算 ( S(n)=sumlimits_{i=1}^{n}f×mu )

    像杜教筛(https://blog.csdn.net/a1799342217/article/details/80328510)一样写一写式子,因为有 ( mu ) 所以把补的 g 函数设为 1 函数。

      ( sumlimits_{i=1}^{n}f×mu×1(i) )

     ( = sumlimits_{i=1}^{n}sumlimits_{d|D}1(d)*(f×mu)(frac{i}{d}) )

     ( = sumlimits_{d=1}^{n}1(d)sumlimits_{i=1}^{frac{n}{d}}f×mu (i) )

     ( = sumlimits_{d=1}^{n}1(d)S(frac{n}{d}) )

    用这个表示 ( S(n) ),则

      ( S(n)=sumlimits_{d=1}^{n}1(d)S(frac{n}{d}) - sumlimits_{d=2}^{n}1(d)S(frac{n}{d}) )

      ( S(n)=sumlimits_{i=1}^{n}f×mu×1(i)- sumlimits_{d=2}^{n}1(d)S(frac{n}{d}) )

      ( S(n)=sumlimits_{i=1}^{n}f(i)- sumlimits_{d=2}^{n}1(d)S(frac{n}{d}) )

    用和 UOJ 188 一样的方法求 f 的前缀和即可。

     S 的可能角标一定是某个 ( leftlfloorfrac{n}{i} ight floor ) 。所以 S 可以预处理。预处理的时候别忘了记忆化。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #define int unsigned int
    #define ll long long
    using namespace std;
    int pw(int x,int k)
    {int ret=1;while(k){if(k&1)ret*=x;x*=x;k>>=1;}return ret;}
    const int N=9e4+5;
    int n,k,base,s[N],g[N],w[N],m,p[N],pk[N],cnt,ans[N];
    bool vis[N];ll p2[N];
    int Id(int x){return x<=base?m-x+1:n/x;}
    int S(int n)
    {
      int k=Id(n);if(ans[k]!=-1)return ans[k];
      int ret=s[k]+g[k];
      for(int i=2,j;i<=n;i=n/j+1)
        {j=n/i;ret-=(n/j-i+1)*S(j);}
      return ans[k]=ret;
    }
    void init(int n)
    {
      base=sqrt(n);
      for(int i=2;i<=base;i++)
        {
          if(!vis[i])p[++cnt]=i,p2[cnt]=(ll)i*i,pk[cnt]=pw(i,k);
          for(int j=1,d;j<=cnt&&(d=i*p[j])<=base;j++)
        {vis[d]=1;if(i%p[j]==0)break;}
        }
      for(int i=1,j;i<=n;i=n/j+1)w[++m]=j=n/i;
    
      for(int i=1;i<=m;i++)g[i]=w[i]-1;
      for(int j=1,tp=0;j<=cnt;j++,tp++)
        for(int i=1;i<=m&&p2[j]<=w[i];i++)
          g[i]-=g[Id(w[i]/p[j])]-tp;
    
      int p0=1;
      for(int j=cnt;j;j--)
        {
          while(p0<=m&&p2[j]<=w[p0])p0++;
          for(int i=p0-1;i;i--)
        {
          int k=Id(w[i]/p[j]);
          s[i]+=s[k]+pk[j]*(g[k]-(j-1));
        }
        }
      memset(ans,-1,sizeof ans);
      S(n);
    }
    signed main()
    {
      scanf("%u%u",&n,&k);init(n);int prn=0;
      for(int i=1,j,lst=0,nw;i<=n;i=n/j+1)
        {
          j=n/i;nw=ans[Id(n/j)];
          prn+=j*j*(nw-lst);lst=nw;
        }
      printf("%u
    ",prn);
      return 0;
    }
  • 相关阅读:
    1. 马尔科夫决策过程
    梯度下降法、随机梯度下降法、小批量梯度下降法
    计算曲线与坐标轴的面积
    鼠标进入,显示div
    codewar
    Django firstDay
    C#学习之关于lock
    winfrom 界面中表格数据修改及刷新(DEV)
    SVN 分支合并 版本控制
    wpf 绑定非元素对象
  • 原文地址:https://www.cnblogs.com/Narh/p/10284725.html
Copyright © 2020-2023  润新知