1. 程式人生 > 其它 >AtCoder Beginner Contest 250 解題報告

AtCoder Beginner Contest 250 解題報告

這裡是事隔 \(n\) 個月的解題報告,由於 A 至 C 題過於簡單,本解題報告從 D 題開始。


D

Description

若一個正整數 \(k\) 滿足 \(k = p \times q^3\)(其中 \(p, q\) 均為質數且 \(p < q\)),則稱 \(k\) 和 250 相似。

問對於給定的 \(n\),不超過 \(n\) 的正整數中有多少是和 250 相似。多組資料。

資料範圍:\(1 \le n \le 10^{18}\).

Solution

注意到 \(k = p \times q^3\) 中有 \(q^3\),從而不難發現當 \(1 \le n \le 10^{18}\)

時,一個和 250 相似的數中 \(q\) 只能為不超過 \(10^6\) 的質數。

考慮到我們列舉 \(p\) 時只需列舉到 \(\dfrac{n}{q^3}\),所以這個演算法應該會跑的很快,但是由於筆者能力不足,不會分析此演算法的時間複雜度(實際上是沒有仔細想,不過實際可以通過本題)

Code

Code
/*
* @author Nickel_Angel ([email protected])
* @copyright Copyright (c) 2022
*/

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <vector>

using std::min;
using std::max;
using std::sort;
using std::swap;
using std::vector;
using std::pair;

typedef long long ll;

const int maxn = 1e6 + 10;
ll n;
int prime[maxn], tot;
bool vis[maxn];

inline void Euler(int n)
{
    for (int i = 2; i <= n; ++i)
    {
        if (!vis[i])
            prime[++tot] = i;
        for (int j = 1; j <= tot && prime[j] <= n / i; ++j)
        {
            vis[i * prime[j]] = true;
            if (i % prime[j] == 0)
                break;
        }
    }
}

int main()
{
    Euler(1e6);
    scanf("%lld", &n);
    ll q, ans = 0;
    for (int i = 2; i <= tot; ++i)
    {
        q = 1ll * prime[i] * prime[i] * prime[i];
        for (int j = 1; j < i; ++j)
        {
            if (q * prime[j] > n)
                break;
            ++ans;
        }
    }
    printf("%lld\n", ans);
    return 0;
}

E

Description

給定兩個長度為 \(n\) 的陣列 \(\{a_n\}, \{b_n\}\)

現在給定 \(q\) 組詢問,每組詢問形如:由 \(\{a_n\}\) 的前 \(x\) 項組成的集合與 \(\{b_n\}\) 的前 \(y\) 項組成的集合是否相等?如果相等,輸出 Yes,否則輸出 No.

資料範圍:\(1 \le n, q \le 2 \times 10^5, 1 \le a_i, b_i \le 10^9\).

Solution

\(firB_x\) 表明 \(x\)\(\{b_n\}\) 中第一次出現的位置,如果 \(x\)\(\{b_n\}\)

中未出現,則為 \(+\infty\)

考慮對於一個固定的 \(x\),它對於 \(y\) 的答案具有單調性。即對於 \(a_{1 \cdots x}\) 組成的集合,設 \(last\)\(a_{1 \cdots x}\) 中,