Problem
Chef is given a positive integer and we have to convert it to using some operations.
In one operation, Chef can do the following:
- Choose a prime number such that divides .
- Replace with .
However, Chef is also given some triggers of the form ( is prime). Thus, if we divide by in some operation, we also have to multiply by for all triggers of the form .
For example: Consider , and the triggers and exist. In one operation, if we choose to divide by , we have to multiply the result with and . In other words, . Thus, is converted to .
Given a number and triggers of the form (where is always prime), find the minimum number of operations required to convert to modulo . Print if it is not possible to do so.
Input Format
- The first line of each input contains two integers and - the initial integer and the number of triggers given to the Chef.
- The next lines describe the triggers. The of these lines contains two space-separated integers and , denoting that Chef has to multiply by if he choses to divide by in some operation.
- It is guaranteed that for .
Output Format
Output on a new line, the minimum number of operations required to convert to , or print if it is not possible to do so. In case it is possible to convert to , the minimum number of operations can be large, so output it modulo .
Constraints
- is a prime number.
Sample 1:
6 1 2 3
3
Explanation:
We can convert to using operations in the following way:
- Divide by . Since no trigger of the form exists, converts to .
- Divide by . Since exists, is converted to . - Divide by . Since no trigger of the form exists, converts to .
It can be proven that we cannot convert to in less than operations.
Sample 2:
4 3 2 5 2 3 3 7
8
Sample 3:
2 3 2 3 3 5 5 3
-1
Explanation:
We can not convert to
using any finite number of operations.
#include "bits/stdc++.h"
// #pragma GCC optimize("O3,unroll-loops")
// #pragma GCC target("avx2,bmi,bmi2,lzcnt,popcnt")
using namespace std;
using ll = long long int;
mt19937_64 rng(chrono::high_resolution_clock::now().time_since_epoch().count());
int main()
{
ios::sync_with_stdio(false); cin.tie(0);
const int LIM = 1e6 + 5, mod = 998244353;
vector<int> spf(LIM);
for (int i = LIM-1; i >= 2; --i) {
for (int j = i; j < LIM; j += i) spf[j] = i;
}
int n, m; cin >> n >> m;
vector<vector<int>> adj(LIM);
for (int i = 0; i < m; ++i) {
int a, b; cin >> a >> b;
while (b > 1) {
int p = spf[b];
b /= p;
adj[a].push_back(p);
}
}
int ans = 0, bad = 0;
vector<int> cost(LIM, -1), mark(LIM);
auto calc = [&] (const auto &self, int u) -> ll {
if (cost[u] != -1) return cost[u];
if (mark[u] == 1 or bad) {
bad = 1;
return 0;
}
mark[u] = 1;
ll ret = 1;
for (int v : adj[u]) {
ret += self(self, v);
ret %= mod;
}
mark[u] = 2;
return cost[u] = ret;
};
while (n > 1) {
int p = spf[n];
ans += calc(calc, p); ans %= mod;
n /= p;
}
if (bad) cout << -1 << '\n';
else cout << ans << '\n';
}
0 Comments