zoukankan      html  css  js  c++  java
  • loj 572 Misaka Network 与求和 —— min_25筛

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

    推式子:https://www.cnblogs.com/cjoieryl/p/10150718.html

    又学习了一下杜教筛hh;

    原来 unsigned int 的输出是 %u 啊;

    注意各处还是要用 (ll),不要不小心都写成 (uint) 了;

    然而递归版很慢...

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    typedef unsigned int uint;
    typedef long long ll;
    int const xn=1e6+5;
    int n,m,K,pri[xn],cnt,w[xn],sqr;
    uint prk[xn],h[xn],G[xn];
    bool vis[xn];
    uint pw(uint a,int b){uint ret=1; for(;b;b>>=1,a=a*a)if(b&1)ret=ret*a; return ret;}
    void init(int mx)
    {
      for(int i=2;i<=mx;i++)
        {
          if(!vis[i])pri[++cnt]=i,prk[cnt]=pw(i,K);
          for(int j=1;j<=cnt&&(ll)i*pri[j]<=mx;j++)
        {
          vis[i*pri[j]]=1;
          if(i%pri[j]==0)break;
        }
        }
    }
    int Id(int x)
    {
      if(x>sqr)return n/x;
      return m-x+1;
    }
    uint F(int x,int y)
    {
      if(pri[y]>x)return 0;
      uint ret=0;
      for(int i=y;i<=cnt&&(ll)pri[i]*pri[i]<=x;i++)//ll
        for(ll p0=pri[i];p0*pri[i]<=x;p0*=pri[i])
          ret+=F(x/p0,i+1)+(uint)prk[i]*(h[Id(x/p0)]-i+1);
      return ret;
    }
    uint S(int x)
    {
      if(G[Id(x)]!=-1)return G[Id(x)];
      uint ret=F(x,1)+h[Id(x)];
      for(int i=2,j;i<=x;i=j+1)j=x/(x/i),ret-=(j-i+1)*S(x/i);
      return G[Id(x)]=ret;
    }
    int main()
    {
      scanf("%d%d",&n,&K); sqr=sqrt(n); init(sqr);
      for(int i=1,j;i<=n;i=j+1)
        {w[++m]=n/i; j=n/w[m]; h[m]=w[m]-1;}
      for(int j=1;j<=cnt;j++)
        for(int i=1;i<=m&&(ll)pri[j]*pri[j]<=w[i];i++)
          h[i]=h[i]-h[Id(w[i]/pri[j])]+j-1;//w[i]
      memset(G,-1,sizeof G);
      uint ans=0;
      for(int T=1,nxt;T<=n;T=nxt+1)
        {
          nxt=n/(n/T);
          ans+=(uint)(n/T)*(n/T)*(S(nxt)-S(T-1));
        }
      printf("%u
    ",ans);//
      return 0;
    }
    递归版

    于是写成了循环版,真的变快了^_^

    代码如下:

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    typedef unsigned int uint;
    typedef long long ll;
    int const xn=1e6+5;
    int n,m,K,pri[xn],cnt,w[xn],sqr;
    uint prk[xn],h[xn],G[xn],f[xn];
    bool vis[xn];
    uint pw(uint a,int b){uint ret=1; for(;b;b>>=1,a=a*a)if(b&1)ret=ret*a; return ret;}
    void init(int mx)
    {
      for(int i=2;i<=mx;i++)
        {
          if(!vis[i])pri[++cnt]=i,prk[cnt]=pw(i,K);
          for(int j=1;j<=cnt&&(ll)i*pri[j]<=mx;j++)
        {
          vis[i*pri[j]]=1;
          if(i%pri[j]==0)break;
        }
        }
    }
    int Id(int x)
    {
      if(x>sqr)return n/x;
      return m-x+1;
    }
    void getf()
    {
      for(int i=cnt;i;i--)
        for(int j=1;j<=m&&(ll)pri[i]*pri[i]<=w[j];j++)
          for(ll p0=pri[i];p0*pri[i]<=w[j];p0*=pri[i])
        f[j]+=f[Id(w[j]/p0)]+(uint)prk[i]*(h[Id(w[j]/p0)]-i+1);
    }
    uint S(int x)
    {
      if(G[Id(x)]!=-1)return G[Id(x)];
      uint ret=f[Id(x)]+h[Id(x)];
      for(int i=2,j;i<=x;i=j+1)j=x/(x/i),ret-=(j-i+1)*S(x/i);
      return G[Id(x)]=ret;
    }
    int main()
    {
      scanf("%d%d",&n,&K); sqr=sqrt(n); init(sqr);
      for(int i=1,j;i<=n;i=j+1)
        {w[++m]=n/i; j=n/w[m]; h[m]=w[m]-1;}
      for(int j=1;j<=cnt;j++)
        for(int i=1;i<=m&&(ll)pri[j]*pri[j]<=w[i];i++)
          h[i]=h[i]-h[Id(w[i]/pri[j])]+j-1;//w[i]
      memset(G,-1,sizeof G);
      uint ans=0; getf();
      for(int T=1,nxt;T<=n;T=nxt+1)
        {
          nxt=n/(n/T);
          ans+=(uint)(n/T)*(n/T)*(S(nxt)-S(T-1));
        }
      printf("%u
    ",ans);//
      return 0;
    }
  • 相关阅读:
    Mybatis批量插入
    easyui中datagrid常见功能
    mysql下载和安装方式
    Mybatis注意事项
    ol3对地图上某些特定的经纬度进行标注
    ol3开发离线地图
    java利用poi生成excel文件后下载本地
    log4j的基本使用方法
    tomcat8.5之后版本,远程无法登录管理页面
    但构造函数返回对象时
  • 原文地址:https://www.cnblogs.com/Zinn/p/10284492.html
Copyright © 2011-2022 走看看