Educational Codeforces Round 138 D Counting Arrays
Counting Arrays
素数
有歧义的数组很难求,但是没有歧义的数组很好求
要使 \(a_i\) 到第一个位置之前都不能被删掉,则 \(2\) 到 \(i\) 的所有数字和 \(a_i\) 的 gcd
不等于 \(1\)
满足这样的条件,代表包含其 \(2\) 到 \(i\) 的所有素数因数即可,因此设 \(2\) 到 \(i\) 质数乘积为 \(p\),不大于 \(m\) 的所有满足上述要求的数量为 \(\lfloor \frac{m}{p} \rfloor\)
注意 \(m\) 还是挺大的,要记得取模,不要直接乘了
#include <iostream>
#include <cstdio>
using namespace std;
typedef long long ll;
const ll mod = 998244353;
ll gcd(ll a, ll b)
{
return b == 0 ? a : gcd(b, a % b);
}
ll qpow(ll x, ll n)
{
ll ans = 1;
while(n)
{
if(n & 1) ans = ans * x % mod;
n >>= 1;
x = x * x % mod;
}
}
int main()
{
ll n, m;
cin >> n >> m;
ll ans = 0, p = 1, now = 1, tot = 0, snow = 1;
for(int i=1; i<=n; i++)
{
if(p <= m)
{
ll f = 1;
for(int j=1; j<i; j++)
f = max(f, gcd(j, i));
if(f == 1) p = p * gcd(p, i) * i;
}
ll k = m / p % mod;
now = now * k % mod;
ans = (ans + now) % mod;
snow = snow * (m % mod) % mod;
tot = (tot + snow) % mod;
}
ans = (tot - ans + mod) % mod;
cout << ans << endl;
return 0;
}