16C - Monitor

Click to show code.


using namespace std;
using ll = long long;
ll a, b, x, y, d, xp, yp;
ll gcd(ll a, ll b) { return (b ? gcd(b, a % b) : a); }
ll binary_search(ll low, ll high)
{
    auto p = [&](ll k) { return b < k * yp; };
    while (low < high)
    {
        ll mid = low + (high - low + 1) / 2;
        if (p(mid))
            high = mid - 1;
        else
            low = mid;
    }
    if (p(low))
        return 0;
    return low;
}
int main(void)
{
    ll ap, bp;
    cin >> a >> b >> x >> y;
    d = gcd(x, y);
    xp = x / d;
    yp = y / d;
    ap = xp * binary_search(0, a / xp);
    bp = y * ap / x;
    cout << ap << " " << bp << endl;
    return 0;
}


1688 - Company Queries Ii

Click to show code.


using namespace std;
using ll = long long;
using ii = pair<int, int>;
using vi = vector<int>;
template <typename InputIterator,
          typename T = typename iterator_traits<InputIterator>::value_type>
void read_n(InputIterator it, int n)
{
    copy_n(istream_iterator<T>(cin), n, it);
}
template <typename InputIterator,
          typename T = typename iterator_traits<InputIterator>::value_type>
void write(InputIterator first, InputIterator last, const char *delim = "\n")
{
    copy(first, last, ostream_iterator<T>(cout, delim));
}
int const NMAX = 2e5 + 11;
int const LMAX = 20;
int const BITS = sizeof(int) * 8;
int n, timer, tin[NMAX], tout[NMAX], up[NMAX][LMAX];
vi g[NMAX];
void dfs(int u, int p)
{
    tin[u] = ++timer;
    up[u][0] = p;
    for (int i = 1; i < LMAX; ++i)
        up[u][i] = up[up[u][i - 1]][i - 1];
    for (int v : g[u])
        if (v != p)
            dfs(v, u);
    tout[u] = ++timer;
}
bool is_ancestor(int u, int v)
{
    return tin[u] <= tin[v] and tout[u] >= tout[v];
}
int lca(int u, int v)
{
    if (is_ancestor(u, v))
        return u;
    if (is_ancestor(v, u))
        return v;
    for (int i = LMAX - 1; i >= 0; --i)
    {
        if (!is_ancestor(up[u][i], v))
            u = up[u][i];
    }
    return up[u][0];
}
int main(void)
{
    ios::sync_with_stdio(false), cin.tie(NULL);
    int q;
    cin >> n >> q;
    for (int i = 2; i <= n; ++i)
    {
        int ei;
        cin >> ei;
        g[ei].push_back(i);
        g[i].push_back(ei);
    }
    dfs(1, 1);
    while (q--)
    {
        int u, v;
        cin >> u >> v;
        cout << lca(u, v) << endl;
    }
    return 0;
}


1687 - Company Queries I

Click to show code.


using namespace std;
using ll = long long;
using ii = pair<int, int>;
using vi = vector<int>;
template <typename InputIterator,
          typename T = typename iterator_traits<InputIterator>::value_type>
void read_n(InputIterator it, int n)
{
    copy_n(istream_iterator<T>(cin), n, it);
}
template <typename InputIterator,
          typename T = typename iterator_traits<InputIterator>::value_type>
void write(InputIterator first, InputIterator last, const char *delim = "\n")
{
    copy(first, last, ostream_iterator<T>(cout, delim));
}
int const NMAX = 2e5 + 11;
int const LMAX = 20;
int const BITS = sizeof(int) * 8;
int n, timer, tin[NMAX], tout[NMAX], up[NMAX][LMAX];
vi g[NMAX];
void dfs(int u, int p)
{
    tin[u] = ++timer;
    up[u][0] = p;
    for (int i = 1; i < LMAX; ++i)
    {
        up[u][i] = up[up[u][i - 1]][i - 1];
    }
    for (int v : g[u])
        if (v != p)
            dfs(v, u);
    tout[u] = ++timer;
}
int ancestor(int u, int k)
{
    int i;
    while (k)
    {
        i = BITS - __builtin_clz(k) - 1;
        u = up[u][i];
        k ^= 1LL << i;
    }
    if (u == 0)
        return -1;
    return u;
}
int main(void)
{
    ios::sync_with_stdio(false), cin.tie(NULL);
    int q;
    cin >> n >> q;
    for (int i = 2; i <= n; ++i)
    {
        int ei;
        cin >> ei;
        g[ei].push_back(i);
        g[i].push_back(ei);
    }
    dfs(1, 0);
    while (q--)
    {
        int x, k;
        cin >> x >> k;
        cout << ancestor(x, k) << endl;
    }
    return 0;
}


1686 - Coin Collector

Click to show code.


using namespace std;
using ll = long long;
using vi = vector<int>;
const int NMAX = 1e5 + 11;
int n, m, n_comp, comp[NMAX];
bool vis[NMAX];
ll ans, coins[NMAX], comp_coins[NMAX], dp[NMAX];
vi g[NMAX], gi[NMAX], gc[NMAX], order;
void toposort(int u)
{
    vis[u] = true;
    for (auto v : g[u])
        if (not vis[v])
            toposort(v);
    order.push_back(u);
}
void build_ssc(int u)
{
    comp[u] = n_comp;
    comp_coins[n_comp] += coins[u];
    for (auto v : gi[u])
        if (comp[v] == -1)
            build_ssc(v);
}
void dfs(int u)
{
    for (auto v : gc[u])
    {
        if (not dp[v])
            dfs(v);
        dp[u] = max(dp[u], dp[v]);
    }
    dp[u] += comp_coins[u];
}
int main(void)
{
    int u, v;
    cin >> n >> m;
    for_each(coins, coins + n, [](ll &c) { cin >> c; });
    for (int i = 0; i < m; ++i)
    {
        cin >> u >> v, --u, --v;
        g[u].push_back(v);
        gi[v].push_back(u);
    }
    for (int u = 0; u < n; ++u)
        if (not vis[u])
            toposort(u);
    memset(comp, -1, sizeof(comp));
    for_each(order.rbegin(), order.rend(), [](int u) {
        if (::comp[u] == -1)
            ::build_ssc(u), ++::n_comp;
    });
    for (int u = 0; u < n; ++u)
        for (auto v : g[u])
            if (comp[u] != comp[v])
                gc[comp[u]].push_back(comp[v]);
    for (int u = 0; u < n_comp; ++u)
        if (not dp[u])
            dfs(u), ans = max(ans, dp[u]);
    cout << ans << endl;
    return 0;
}


1684 - Giant Pizza

Click to show code.


using namespace std;
using vi = vector<int>;
const int NMAX = 2e5 + 11;
int n, m, cur_comp, comp[NMAX];
bool vis[NMAX], ans[NMAX];
vi g[NMAX], gi[NMAX], order;
inline int id(int u, char c) { return 2 * u + (c != '+'); }
inline int neg(int u) { return u ^ 1; }
void dfs1(int u)
{
    vis[u] = true;
    for (auto v : g[u])
        if (not vis[v])
            dfs1(v);
    order.push_back(u);
}
void dfs2(int u)
{
    comp[u] = cur_comp;
    for (auto v : gi[u])
        if (not comp[v])
            dfs2(v);
}
bool solve(void)
{
    for (int u = 0; u < 2 * n; ++u)
        if (not vis[u])
            dfs1(u);
    for_each(order.rbegin(), order.rend(), [](int u) {
        if (not comp[u])
            ++cur_comp, ::dfs2(u);
    });
    for (int u = 0; u < 2 * n; u += 2)
    {
        if (comp[u] == comp[u + 1])
            return false;
        ans[u / 2] = comp[u] > comp[u + 1];
    }
    return true;
}
int main(void)
{
    char c1, c2;
    int u, v;
    cin >> m >> n;
    for (int i = 0; i < m; ++i)
    {
        cin >> c1 >> u >> c2 >> v, u--, v--;
        u = id(u, c1), v = id(v, c2);
        g[neg(u)].push_back(v);
        g[neg(v)].push_back(u);
        gi[v].push_back(neg(u));
        gi[u].push_back(neg(v));
    }
    if (solve())
        for_each(ans, ans + n, [](bool x) { cout << (x ? '+' : '-') << " "; }),
            cout << endl;
    else
        cout << "IMPOSSIBLE" << endl;
    return 0;
}


1683 - Planets And Kingdoms

Click to show code.


using namespace std;
using vi = vector<int>;
const int NMAX = 1e5 + 11;
int n, m, cur_kingdom, kingdom[NMAX];
bool vis[NMAX];
vi g[NMAX], gi[NMAX], order;
void toposort(int u)
{
    vis[u] = true;
    for (auto v : g[u])
        if (not vis[v])
            toposort(v);
    order.push_back(u);
}
void buildscc(int u)
{
    vis[u] = true;
    kingdom[u] = cur_kingdom;
    for (auto v : gi[u])
        if (not vis[v])
            buildscc(v);
}
int main(void)
{
    int u, v;
    cin >> n >> m;
    for (int i = 0; i < m; ++i)
    {
        cin >> u >> v;
        g[u].push_back(v);
        gi[v].push_back(u);
    }
    memset(vis, 0, sizeof(vis));
    for (int u = 1; u <= n; ++u)
        if (not vis[u])
            toposort(u);
    memset(vis, 0, sizeof(vis));
    for_each(order.rbegin(), order.rend(), [](int u) {
        if (not vis[u])
            ++cur_kingdom, buildscc(u);
    });
    cout << cur_kingdom << endl;
    for_each(kingdom + 1, kingdom + n + 1, [](int k) { cout << k << " "; }),
        cout << endl;
    return 0;
}


1682 - Flight Routes Check

Click to show code.


using namespace std;
using vi = vector<int>;
const int NMAX = 1e5 + 11;
int n, m, x, y, visited[NMAX];
vi g[NMAX], gi[NMAX];
void dfs(int u, const vi gr[], int vval)
{
    visited[u] = vval;
    for (auto v : gr[u])
        if (visited[v] != vval)
            dfs(v, gr, vval);
}
bool vis_check(int vval, int &ans)
{
    for (int u = 1; u <= n; ++u)
    {
        if (visited[u] != vval)
        {
            ans = u;
            return false;
        }
    }
    return true;
}
bool solve(void)
{
    int vval;
    dfs(1, g, vval = 1), x = 1;
    if (not vis_check(vval, y))
        return false;
    dfs(1, gi, vval = 2), y = 1;
    if (not vis_check(vval, x))
        return false;
    return true;
}
int main(void)
{
    int u, v;
    cin >> n >> m;
    for (int i = 0; i < m; ++i)
    {
        cin >> u >> v;
        g[u].push_back(v);
        gi[v].push_back(u);
    }
    if (solve())
        cout << "YES" << endl;
    else
    {
        cout << "NO" << endl;
        cout << x << " " << y;
    }
    return 0;
}


1681 - Game Routes

Click to show code.


using namespace std;
using vi = vector<int>;
using ll = long long;
const int NMAX = 1e5 + 11;
const int MOD = 1e9 + 7;
int n, m;
bool visited[NMAX];
vi g[NMAX], gi[NMAX], vsorted;
int add(ll a, ll b) { return ((a % MOD) + (b % MOD)) % MOD; }
void toposort(int u)
{
    for (auto v : g[u])
    {
        if (visited[v])
            continue;
        toposort(v);
    }
    visited[u] = true;
    vsorted.push_back(u);
}
int main(void)
{
    ios_base::sync_with_stdio(false), cin.tie(NULL);
    int u, v;
    cin >> n >> m;
    for (int i = 0; i < m; ++i)
    {
        cin >> u >> v;
        g[u].push_back(v);
        gi[v].push_back(u);
    }
    toposort(1);
    reverse(vsorted.begin(), vsorted.end());
    vi dp(n + 1, 0);
    dp[1] = 1;
    for (auto v : vsorted)
    {
        for (auto u : gi[v])
        {
            if (visited[u])
                dp[v] = add((ll)dp[v], (ll)dp[u]);
        }
    }
    cout << dp[n] << endl;
    return 0;
}


1680 - Longest Flight Route

Click to show code.


using namespace std;
using vi = vector<int>;
const int NMAX = 1e5 + 11;
int n, m;
bool visited[NMAX];
vi g[NMAX], gi[NMAX], vsorted;
void toposort(int u)
{
    for (auto v : g[u])
    {
        if (visited[v])
            continue;
        toposort(v);
    }
    visited[u] = true;
    vsorted.push_back(u);
}
int main(void)
{
    ios_base::sync_with_stdio(false), cin.tie(NULL);
    int u, v;
    cin >> n >> m;
    for (int i = 0; i < m; ++i)
    {
        cin >> u >> v;
        g[u].push_back(v);
        gi[v].push_back(u);
    }
    toposort(1);
    if (not visited[n])
    {
        cout << "IMPOSSIBLE" << endl;
    }
    else
    {
        reverse(vsorted.begin(), vsorted.end());
        vi dp(n + 1, 0), pre(n + 1, 0), ans;
        for (auto v : vsorted)
        {
            for (auto u : gi[v])
            {
                if (visited[u] and dp[u] + 1 > dp[v])
                {
                    dp[v] = dp[u] + 1;
                    pre[v] = u;
                }
            }
        }
        cout << dp[n] + 1 << endl;
        int u = n;
        do
        {
            ans.push_back(u);
            u = pre[u];
        } while (pre[u]);
        ans.push_back(u);
        for_each(ans.rbegin(), ans.rend(), [](int x) { cout << x << " "; }),
            cout << endl;
    }
    return 0;
}


1679 - Course Schedule

Click to show code.


using namespace std;
using vi = vector<int>;
const int NMAX = 1e5 + 11;
int n, m;
vi g[NMAX], ans, color;
bool dfs(int u)
{
    if (color[u] == 1)
        return false;
    if (color[u] == 2)
        return true;
    color[u] = 1;
    for (int v : g[u])
    {
        if (not dfs(v))
            return false;
    }
    color[u] = 2;
    ans.push_back(u);
    return true;
}
bool toposort(void)
{
    color.assign(n + 1, 0);
    for (int u = 1; u <= n; ++u)
    {
        if (not color[u] and not dfs(u))
            return false;
    }
    return true;
}
int main(void)
{
    int u, v;
    cin >> n >> m;
    for (int i = 0; i < m; ++i)
    {
        cin >> u >> v;
        g[u].push_back(v);
    }
    if (toposort())
        for_each(ans.rbegin(), ans.rend(), [](int x) { cout << x << " "; }),
            cout << endl;
    else
        cout << "IMPOSSIBLE" << endl;
    return 0;
}