专栏文章

Solution to CF1749D Counting Arrays

CF1749D题解参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@mind9qb8
此快照首次捕获于
2025/12/02 00:31
3 个月前
此快照最后确认于
2025/12/02 00:31
3 个月前
查看原文
Observe that an arbitrary array aa always has a removal sequence of [1,1,,1][1, 1, \dots, 1], for gcd(a1,1)=1\gcd(a_1, 1) = 1 always holds. Therefore, as long as there exists an index 2in,2ji,gcd(ai,j)=12 \le i \le n, 2\le j \le i, \gcd(a_i, j) = 1, we can obtain another removal sequence by removing the first element until aia_i is shifted to position jj, removing the jj-th element, and removing the first element until every element is removed.
Thus, the problem reduces to counting the number of arrays of length from 11 to nn, where each aia_i is an integer from 11 to mm, satisfying the aforementioned condition.
Consider each length of aa separately.
Assume that the length of aa is a|a|, the number of arrays satisfying the condition equals mam^{|a|} minus the number of arrays aa such that
2ia,2ji,gcd(ai,j)>1\forall 2\le i\le |a|, 2\le j \le i,\gcd(a_i, j) > 1
Let TT denote the number of arrays satisfying the condition above. To compute TT, we consider each aia_i separately.
Let cic_i be the number of integers which aia_i can be. It is obvious that c1=mc_1 = m, because there is no constraint on it.
Since for every 2ji,gcd(ai,j)>12\le j\le i, \gcd(a_i, j) > 1, aia_i must be a multiple of every prime number less than or equal to ii. Let d=2pipd = \prod\limits_{2\le p\le i}p where pp is a prime number. We have ci=mdc_i = \left\lfloor\dfrac{m}{d}\right\rfloor.
The condition holds for every 2ia2\le i \le |a|, so T=i=1aciT = \prod\limits_{i=1}^{|a|} c_i.
The answer is the sum of maTm^{|a|} - T over all 1an1 \le |a| \le n.
Time complexity: Θ(nlogn)\Theta(n \log n) due to the use of exponentiation by squaring.
ImplementationCPP
#include <bits/stdc++.h>

using namespace std;

using ll = long long;
using pii = pair<int, int>;

#ifdef ONLINE_JUDGE
#define debug(...) 0
#else
#define debug(...) fprintf(stderr, __VA_ARGS__), fflush(stderr)
#endif

constexpr int N = 3e5 + 5, mod = 998244353;

int qpow(int a, int b) {
    a %= mod;
    int res = 1;
    while (b) {
        if (b & 1) res = 1ll * res * a % mod;
        a = 1ll * a * a % mod;
        b >>= 1;
    }
    return res;
}

int n; ll m;
ll c[N];

bool notprime[N];
vector<int> primes;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cin >> n >> m;

    for (int i = 2; i <= n; i++) {
        if (!notprime[i]) primes.emplace_back(i);
        for (int j = 0; primes[j] * i <= n; j++) {
            notprime[primes[j] * i] = 1;
            if (i % primes[j] == 0) break;
        }
    }

    ll lc = 1;

    for (int i = 2; i <= n; i++) {
        if (!notprime[i]) {
            if (lc <= m / i) lc *= i;
            else lc = m + 1;
        }
        c[i] = m / lc;
    }

    int ans = 0, prod = m % mod;
    for (int i = 2; i <= n; i++) {
        prod = c[i] % mod * prod % mod;
        ans = ((ans + qpow(m % mod, i)) % mod - prod + mod) % mod;
    }

    cout << ans << "\n";
    return 0;
}

评论

0 条评论,欢迎与作者交流。

正在加载评论...