Codeforces 665F Four Divisors 数论,Min_25筛法

文章目录


题目链接

题意

求小于等于 n n n的正整数中有多少个数刚好有四个约数,其中 n ≤ 1 0 11 n\leq 10^{11} n1011.

题解

显然不能直接筛.经过学习,我们发现 m i n _ 25 min\_25 min_25筛法可以在 O ( n 2 3 ) O(n^{\frac{2}{3}}) O(n32)的复杂度内完成本题.
首先我们可以意识到成立的数字一定是某个质数的三次方或者两个不同质数的乘积,两者没有重合部分,可分开计算.
质数的三次方很好解决,筛出 n \sqrt n n 的质数然后枚举到 n n n即可,关键是后者.
min_25筛可以用来解决类似 ∑ i = 1 n { i ∈ p r i m e } f ( i ) \sum_{i=1}^{n}\{i\in prime \}f(i) i=1n{iprime}f(i)的问题,其中 f ( i ) f(i) f(i)是一个多项式.
本题中需要计算 n n n以内质数的个数,故取 f ( i ) = 1 f(i)=1 f(i)=1.
g ( j , m ) g(j,m) g(j,m)表示小于 m m m的质数或者最小的质因数大于 p j p_j pj的贡献.
转移分为两种情况.

  1. p j 2 > m p_j^2>m pj2>m,这种情况下 p j 2 p_j^2 pj2是最小质因子为 p j p_j pj的最小数,因此合数不可能产生贡献,而只有质数可能再产生贡献,故 g ( j , m ) = g ( j − 1 , m ) g(j,m)=g(j-1,m) g(j,m)=g(j1,m).
  2. p j 2 ≤ m p_j^2\leq m pj2m,此时需要减掉 p j p_j pj是最小质因子的贡献,本题中即为 g ( j , [ n p j ] ) − j + 1 g(j,[\frac{n}{p_j}])-j+1 g(j,[pjn])j+1

然后滚动一下数组就可以了.
最后是对每一个 n \sqrt n n 以内的质数 p p p求满足 p × q ≤ n p\times q\leq n p×qn的质数 q q q的个数,由于前缀和,我们可以轻松算出.
这个答案加上我们一开始算出来的质数立方的个数就是最后的答案了.

#include<bits/stdc++.h> //Ithea Myse Valgulious
/*省略输入头文件*/
using namespace std;
const int mulu=8e5;
typedef ll fuko[mulu|10];
fuko mp,mp1,mp2,g,pr,p;
ll min_25(ll n) {
  ll i,j,m=sqrt(n+.5);
  for (i=2;i<=mulu;++i) {
    if (!p[i]) pr[++*pr]=i;
    for (j=1;j<=*pr&&pr[j]*i<=mulu;++j) {
      p[pr[j]*i]=1;
      if (i%pr[j]==0) break;
    }
  }
  for (i=1;i<=n;i=j+1) {
    j=n/(n/i);
    mp[++*mp]=n/i;
    mp[*mp]<=m?mp1[mp[*mp]]=*mp:mp2[n/mp[*mp]]=*mp;
    g[*mp]=mp[*mp]-1;
  }
  for (j=1;j<=*pr;++j) {
    for (i=1;i<=*mp&&pr[j]*pr[j]<=mp[i];++i) {
      ll tmp=mp[i]/pr[j];
      tmp=tmp<=m?mp1[tmp]:mp2[n/tmp];
      g[i]-=g[tmp]-j+1;
    }
  }
  ll zw=0;
  for (i=1;i<=*pr&&pr[i]<=m;++i) {
    zw+=g[n/(n/pr[i])]-g[mp1[n/(n/pr[i])]];
  }
  for (i=1;i<=*pr&&pr[i]*pr[i]*pr[i]<=n;++i);
  return zw+i-1;
}
int main() {
  ll n; 
  read(n);
  printf("%lld\n",min_25(n));
}

谢谢大家.

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值