[ABC250D] 250-like Number 三种方法

youhualiuh / 2024-02-27 / 原文

[ABC250D] 250-like Number

题目描述:->题意很简单 主要是方法

素数p, q.  p < q & k = p * q ^ 3则k是250相似的数,给你一个N,求出小于N与250相似的数的数量

Code:

头文件

#include <bits/stdc++.h>
    
using namespace std;
using i64 = long long;

  

求素数的代码我就以欧拉筛来写 对于主函数的代码我们将分类情况  -使用普通的筛选也是可以过的

vector<int> minp, primes;//欧拉筛
void sieve(i64 n) {
    minp.assign(n + 1, 0); primes.clear();
    for (int i = 2; i <= n; i++) {
        if (minp[i] == 0) { minp[i] = i, primes.push_back(i);}
        for (auto p : primes) {
            if (i * p > n) { break; }
            minp[i * p] = p;
            if (p == minp[i]) { break; }
        }
    }
}

  

这里主要使用储存的primes开始 由于数据不大 我采用pow的形式来写->偷懒一下

1-枚举

枚举思路就是第二个素数开始遍历,因为p < q第一个就因此给他舍弃, 不舍弃问题也不大.来后不断枚举直到p * q^3>n作为结束输出就行-》按题意来嘿嘿

int main () {
    ios::sync_with_stdio(false);  cin.tie(0); cout.tie(0);
    sieve(1e6);
    i64 n, cnt = 0; cin >> n;
    int len = primes.size();
    for (int i = 1; i < len; i++) {
        for (int j = 0; j < i; j++) {
            if (1LL * primes[j] * pow(primes[i], 3) > n) { break; }
            cnt++;
        }
    }
    cout << cnt;
}

  

 

2-双指针

从枚举衍生到双指针, 我们从left=0,right=primes.size()-1这两个来进行比较如果a[right]^3*a[left]<n说明right-left这些点都是满足的不用在一个个比较直接left++即可,不满足right--直到p < q这个条件不满足 也就是left<right这两个索引不相同就可以.

int main () {
    ios::sync_with_stdio(false);  cin.tie(0); cout.tie(0);
    sieve(1e6);
    i64 n, cnt = 0; cin >> n;
    int left = 0, right = primes.size() - 1;
    while (left < right) {
        if (1LL * primes[left] * pow(primes[right], 3) <= n) {
            cnt += (right - left);
            left++;
        }
        else {
            right--;
        }
    }
    cout << cnt;
}

  

3-二分

二分这个思路很强,一点就通,我们直接去求出满足a[p]*a[q]*a[q]*a[q]的条件的索引也就是它的满足条件的值,只能说YYDS

int main() {
    ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    sieve(1e6);
    i64 n, cnt = 0; cin >> n;
    i64 len = primes.size();
    for(int i = 0; i < len; i++) {
        i64 x = n / pow(primes[i], 3) * 1LL;
        cnt += upper_bound(primes.begin(), primes.begin() + i, x) - primes.begin();
    }
    cout << cnt;
    return 0;
}