KGSS - Maximum Sum

Click to show code.


using namespace std;
using ii = pair<int, int>;
using vi = vector<int>;
using vii = vector<ii>;
inline int sum_pair(ii a) { return a.first + a.second; }
struct segtree
{
    int n;
    vii t;
    segtree(int n)
    {
        this->n = n;
        t.resize(4 * n);
    }
    segtree(const vi &a) : segtree(a.size()) { build(a, 1, 0, n - 1); }
    ii merge(ii a, ii b) const
    {
        if (a.first < b.first)
            swap(a, b);
        return {a.first, max({a.second, b.second, b.first})};
    }
    void build(const vi &a, int v, int tl, int tr)
    {
        if (tl == tr)
            t[v] = {a[tl], -1};
        else
        {
            int tm = (tl + tr) / 2;
            build(a, 2 * v, tl, tm);
            build(a, 2 * v + 1, tm + 1, tr);
            t[v] = merge(t[2 * v], t[2 * v + 1]);
        }
    }
    void update(int pos, int new_val)
    {
        update_util(1, 0, n - 1, pos, new_val);
    }
    void update_util(int v, int tl, int tr, int pos, int new_val)
    {
        if (pos < tl or tr < pos)
            return;
        else if (tl == tr and tl == pos)
            t[v] = {new_val, -1};
        else
        {
            int tm = (tl + tr) / 2;
            update_util(2 * v, tl, tm, pos, new_val);
            update_util(2 * v + 1, tm + 1, tr, pos, new_val);
            t[v] = merge(t[v * 2], t[v * 2 + 1]);
        }
    }
    int query(int ql, int qr) const
    {
        return sum_pair(query_util(1, 0, n - 1, ql, qr));
    }
    ii query_util(int v, int tl, int tr, int ql, int qr) const
    {
        if (qr < ql)
            return {-1, -1};
        else if (ql == tl and qr == tr)
            return t[v];
        int tm = (tl + tr) / 2;
        return merge(query_util(2 * v, tl, tm, ql, min(tm, qr)),
                     query_util(2 * v + 1, tm + 1, tr, max(tm + 1, ql), qr));
    }
};
int main(void)
{
    int n, qn, ql, qr, pos, x;
    char qtype;
    vi a;
    cin >> n;
    a.resize(n);
    for (auto &x : a)
        cin >> x;
    segtree t(a);
    cin >> qn;
    while (qn--)
    {
        cin >> qtype;
        if (qtype == 'Q')
        {
            cin >> ql >> qr;
            cout << t.query(ql - 1, qr - 1) << endl;
        }
        else
        {
            cin >> pos >> x;
            t.update(pos - 1, x);
        }
    }
    return 0;
}


INVCNT - Inversion Count

Click to show code.


using namespace std;
using vi = vector<int>;
using ll = long long;
const int amax = 1e7 + 11;
struct fenwick
{
    int n;
    vi bit;
    fenwick(int _n) : n(_n + 1) { bit.assign(_n + 1, 0); }
    void point_update(int i, int delta)
    {
        ++i;
        while (i < n)
        {
            bit[i] += delta;
            i += (i & -i);
        }
    }
    ll prefix_sum(int r)
    {
        ll ans = 0;
        ++r;
        while (r > 0)
        {
            ans += bit[r];
            r -= (r & -r);
        }
        return ans;
    }
    ll sum(int l, int r)
    {
        ll ans = prefix_sum(r);
        ans -= prefix_sum(l - 1);
        return ans;
    }
};
int main(void)
{
    int t, n, x;
    ll ans;
    cin >> t;
    while (t--)
    {
        cin >> n;
        fenwick tree(amax + 1);
        ans = 0;
        for (int i = 0; i < n; ++i)
        {
            cin >> x;
            tree.point_update(x, 1);
            ans += tree.sum(x + 1, amax);
        }
        cout << ans << endl;
    }
    return 0;
}


GSS4 - Can You Answer Queries Iv

Click to show code.


using namespace std;
using ll = long long;
const int NMAX = 1e5 + 11;
ll n, a[NMAX], seg[4 * NMAX];
void update(ll v, ll tl, ll tr, ll ql, ll qr);
void build(ll a[], ll v, ll tl, ll tr)
{
    if (tl == tr)
        seg[v] = a[tl];
    else
    {
        ll tm = (tl + tr) / 2;
        build(a, 2 * v, tl, tm);
        build(a, 2 * v + 1, tm + 1, tr);
        seg[v] = seg[2 * v] + seg[2 * v + 1];
    }
}
void lazy_propagate(ll v, ll tl, ll tr)
{
    if (tr - tl + 1 < seg[v])
    {
        if (tl == tr)
        {
            seg[v] = (ll)sqrt(seg[v]);
        }
        else
        {
            ll tm = (tl + tr) / 2;
            update(2 * v, tl, tm, tl, tm);
            update(2 * v + 1, tm + 1, tr, tm + 1, tr);
            seg[v] = seg[2 * v] + seg[2 * v + 1];
        }
    }
}
void update(ll v, ll tl, ll tr, ll ql, ll qr)
{
    if (ql > qr)
        return;
    if (tl == ql and tr == qr)
        lazy_propagate(v, tl, tr);
    else
    {
        ll tm = (tl + tr) / 2;
        update(2 * v, tl, tm, ql, min(tm, qr));
        update(2 * v + 1, tm + 1, tr, max(tm + 1, ql), qr);
        seg[v] = seg[2 * v] + seg[2 * v + 1];
    }
}
ll query(ll v, ll tl, ll tr, ll ql, ll qr)
{
    if (ql > qr)
        return 0;
    else if (tl == ql and tr == qr)
        return seg[v];
    else
    {
        ll tm = (tl + tr) / 2;
        return query(2 * v, tl, tm, ql, min(tm, qr)) +
               query(2 * v + 1, tm + 1, tr, max(tm + 1, ql), qr);
    }
}
int main(void)
{
    ll q, ql, qr, type, tc = 1;
    while (scanf("%lld", &n) != EOF)
    {
        memset(seg, 0, sizeof(seg));
        for (ll i = 0; i < n; ++i)
            scanf("%lld", &a[i]);
        build(a, 1, 0, n - 1);
        scanf("%lld", &q);
        printf("Case #%lld:\n", tc++);
        while (q--)
        {
            scanf("%lld%lld%lld", &type, &ql, &qr);
            if (ql > qr)
                swap(ql, qr);
            if (type == 0)
            {
                update(1, 0, n - 1, ql - 1, qr - 1);
            }
            else
            {
                printf("%lld\n", query(1, 0, n - 1, ql - 1, qr - 1));
            }
        }
        printf("\n");
    }
    return 0;
}


ANDROUND - And Rounds

Click to show code.


using namespace std;
const int NMAX = 2e5 + 11;
int n, a[NMAX], seg[4 * NMAX];
void build(int a[], int v, int tl, int tr)
{
    if (tl == tr)
        seg[v] = a[tl];
    else
    {
        int tm = (tl + tr) / 2;
        build(a, 2 * v, tl, tm);
        build(a, 2 * v + 1, tm + 1, tr);
        seg[v] = seg[2 * v] & seg[2 * v + 1];
    }
}
int query(int v, int tl, int tr, int ql, int qr)
{
    if (ql > qr)
        return -1;
    if (ql == tl and qr == tr)
        return seg[v];
    else
    {
        int tm = (tl + tr) / 2;
        return query(2 * v, tl, tm, ql, min(tm, qr)) &
               query(2 * v + 1, tm + 1, tr, max(tm + 1, ql), qr);
    }
}
int main(void)
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    int t, k, ans, l, r;
    cin >> t;
    while (t--)
    {
        cin >> n >> k;
        for (int i = 0; i < n; ++i)
            cin >> a[i];
        memset(seg, 0, sizeof(seg));
        build(a, 1, 0, n - 1);
        for (int i = 0; i < n; ++i)
        {
            l = i - k;
            r = i + k;
            if (k >= n / 2)
                ans = query(1, 0, n - 1, 0, n - 1);
            else if (0 <= l and r < n)
                ans = query(1, 0, n - 1, l, r);
            else
            {
                if (l < 0)
                {
                    ans = query(1, 0, n - 1, 0, r) &
                          query(1, 0, n - 1, n + l, n - 1);
                }
                if (r >= n)
                {
                    ans = query(1, 0, n - 1, l, n - 1) &
                          query(1, 0, n - 1, 0, r - n);
                }
            }
            cout << ans << " ";
        }
        cout << endl;
    }
    return 0;
}


ADAPET - Ada And Pet

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 = 5e5 + 11;
int n, pi[NMAX];
char s[NMAX];
int prefix_function(string s)
{
    for (int i = 1; i < n; i++)
    {
        int j = pi[i - 1];
        while (j > 0 and s[i] != s[j])
            j = pi[j - 1];
        if (s[i] == s[j])
            j++;
        pi[i] = j;
    }
    return pi[n - 1];
}
int main(void)
{
    int t;
    scanf("%d", &t);
    while (t--)
    {
        int k;
        scanf("%s %d", s, &k);
        n = strlen(s);
        int x = prefix_function(s);
        printf("%lld\n", ll(k - 1) * ll(n - x) + n);
    }
    return 0;
}


ADAINDEX - Ada Indexing

Click to show code.


using namespace std;
const int CMAX = 26;
struct node
{
    int cnt;
    node *children[CMAX];
};
struct trie
{
    node *root;
    trie() { root = new node(); }
    void insert(string s)
    {
        node *cur = root;
        for (auto c : s)
        {
            int j = c - 'a';
            if (cur->children[j] == nullptr)
                cur->children[j] = new node();
            cur = cur->children[j];
            cur->cnt += 1;
        }
    }
    int query(string prefix)
    {
        node *cur = root;
        for (auto c : prefix)
        {
            int j = c - 'a';
            if (cur->children[j] == nullptr)
                return 0;
            cur = cur->children[j];
        }
        return cur->cnt;
    }
};
int main(void)
{
    int n, q;
    string s;
    trie t;
    cin >> n >> q;
    while (n--)
    {
        cin >> s;
        t.insert(s);
    }
    while (q--)
    {
        cin >> s;
        cout << t.query(s) << endl;
    }
    return 0;
}


9A - Die Roll

Click to show code.


using namespace std;
string ans[6] = {"1/6", "1/3", "1/2", "2/3", "5/6", "1/1"};
int main(void)
{
    int y, w, x;
    cin >> y >> w;
    x = 6 - max(y, w) + 1;
    cout << ans[x - 1] << endl;
    return 0;
}


99B - Help Chef Garasim

Click to show code.


using namespace std;
using pii = pair<int, int>;
const int NMAX = 1e3 + 11;
pii a[NMAX];
int main(void)
{
    int n, ai;
    cin >> n;
    for (int i = 1; i <= n; ++i)
    {
        cin >> ai;
        a[i - 1] = {ai, i};
    }
    sort(a, a + n);
    if (a[0].first == a[n - 1].first)
        cout << "Exemplary pages." << endl;
    else
    {
        int diff = a[n - 1].first - a[0].first;
        if (diff % 2 == 0)
        {
            bool recoverable = false;
            int normal = a[0].first + diff / 2;
            if (n == 2)
                recoverable = true;
            else if (n == 3 and a[1].first == normal)
                recoverable = true;
            else if (n >= 4 and a[1].first == normal and
                     a[n - 2].first == normal)
                recoverable = true;
            if (recoverable)
                cout << diff / 2 << " ml. from cup #" << a[0].second
                     << " to cup #" << a[n - 1].second << "." << endl;
            else
                cout << "Unrecoverable configuration." << endl;
        }
        else
            cout << "Unrecoverable configuration." << endl;
    }
    return 0;
}


977F - Consecutive Subsequence

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));
}
vi solve(int n, vi a)
{
    set<ii> sorted;
    for (int i = 0; i < n; ++i)
        sorted.emplace(a[i], i);
    vi dp(n + 1, 0);
    dp[1] = 1;
    for (int i = 1; i <= n; ++i)
    {
        dp[i] = 1;
        auto it = sorted.lower_bound({a[i - 1] - 1, i - 1});
        if (it == sorted.begin() or prev(it)->first != a[i - 1] - 1)
            continue;
        auto [aj, j] = *prev(it);
        dp[i] += dp[j + 1];
    }
    int i = distance(dp.begin(), max_element(dp.begin(), dp.end())) - 1, m = dp[i + 1],
        x = a[i];
    vi ans(m);
    for (int j = m - 1; j >= 0; --j)
    {
        ans[j] = i + 1;
        auto it = sorted.lower_bound({x - 1, i});
        if (j > 0)
        {
            it--;
            x = it->first;
            i = it->second;
        }
    }
    return ans;
}
int main(void)
{
    ios::sync_with_stdio(false), cin.tie(NULL);
    int n;
    cin >> n;
    vi a(n);
    read_n(a.begin(), n);
    vi ans = solve(n, a);
    cout << (int)ans.size() << endl;
    write(ans.begin(), ans.end(), " "), cout << endl;
    return 0;
}


919D - Substring

Click to show code.


using namespace std;
using ll = long long;
using ii = pair<int, int>;
using vi = vector<int>;
int const NMAX = 3e5 + 11;
int n, m, visited[NMAX], dp[NMAX][26];
vi g[NMAX], order;
string ch;
bool dfs1(int u)
{
    if (visited[u] == 1)
        return false;
    if (visited[u] == 2)
        return true;
    visited[u] = 1;
    for (auto v : g[u])
        if (not dfs1(v))
            return false;
    visited[u] = 2;
    order.push_back(u);
    return true;
}
bool toposort(void)
{
    memset(visited, 0, sizeof(visited));
    for (int u = 0; u < n; ++u)
        if (not visited[u] and not dfs1(u))
            return false;
    return true;
}
void dfs2(int u)
{
    if (visited[u])
        return;
    for (auto v : g[u])
    {
        dfs2(v);
        for (int c = 0; c < 26; ++c)
            dp[u][c] = max(dp[u][c], dp[v][c]);
    }
    visited[u] = true;
    dp[u][ch[u] - 'a']++;
}
int solve(void)
{
    int ans = 0;
    memset(visited, 0, sizeof(visited));
    reverse(order.begin(), order.end());
    for (auto u : order)
    {
        if (not visited[u])
        {
            dfs2(u);
            ans = max(ans, *max_element(dp[u], dp[u] + 26));
        }
    }
    return ans;
}
int main(void)
{
    ios_base::sync_with_stdio(false), cin.tie(NULL);
    int u, v;
    cin >> n >> m >> ch;
    for (int i = 0; i < m; ++i)
    {
        cin >> u >> v, u--, v--;
        g[u].push_back(v);
    }
    if (toposort())
        cout << solve() << endl;
    else
        cout << -1 << endl;
    return 0;
}