zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    单模光纤与多模光纤的区别
    普通的单模光纤和单模光纤跳线是否可以达到万兆速度?
    原创:在局域网中,如何知道某个IP被占用 show arp
    如何知道局域网内哪些ip被占用----工具法Free IP Scanner
    如何知道局域网内哪些ip被占用
    科普知识普及
    电脑通电自动开机
    2.4G还是5G?带你选择最正确的路由器
    光纤收发器指示灯介绍
    100BASE-TX、100Base-FX等含义
  • 原文地址:https://www.cnblogs.com/Narh/p/10284725.html
Copyright © 2011-2022 走看看