Editorial for 第2回卬高杯 I問題 - Hyper Janken(easy)


Remember to use this editorial only when stuck, and not to copy-paste code from it. Please be respectful to the problem author and editorialist.
Submitting an official solution before solving the problem yourself is a bannable offence.

Author: admin

C++

C++20

#include <algorithm>                // for max, min
#include <atcoder/internal_bit.hpp> // for atcoder
#include <atcoder/modint.hpp>       // for modint998244353
#include <atcoder/segtree.hpp>      // for segtree
#include <iostream>                 // for basic_istream::operator>>, opera...
#include <tuple>                    // for tie, tuple
#include <utility>                  // for make_pair, pair

using namespace std;
using namespace atcoder;
using mint = modint998244353;
using pint = pair<int, int>;
#define mkpr make_pair

int n, m;

pint op(pint a, pint b)
{
    int a1, a2, b1, b2;
    tie(a1, a2) = a;
    tie(b1, b2) = b;
    if (a1 == -1)
        return b; // 初期値が入っていたら、もう片方を返す
    if (b1 == -1)
        return a; // 初期値が(略)
    if (a1 == 2 * n + 1)
        return a; // あいこになっていたら、あいこを返す
    if (b1 == 2 * n + 1)
        return b; // あいこに(略)

    if ((b2 - a1 + (2 * n + 1)) % (2 * n + 1) <= n && (a2 - b1 + (2 * n + 1)) % (2 * n + 1) <= n && (b1 - a1 + (2 * n + 1)) % (2 * n + 1) <= n && (a2 - b2 + (2 * n + 1)) % (2 * n + 1) <= n)
        return a; // bがaに含まれるならaを返す
    else if (((a2 - b1 + (2 * n + 1)) % (2 * n + 1) <= n) && (b2 - a1 + (2 * n + 1)) % (2 * n + 1) <= n && (a1 - b1 + (2 * n + 1)) % (2 * n + 1) <= n && (b2 - a2 + (2 * n + 1)) % (2 * n + 1) <= n)
        return b; // aがbに含まれるならbを返す
    else if ((b2 - a1 + (2 * n + 1)) % (2 * n + 1) <= n)
        return mkpr(a1, b2); // aの後にbがあるなら連結
    else if ((a2 - b1 + (2 * n + 1)) % (2 * n + 1) <= n)
        return mkpr(b1, a2); // bの後にaがあるなら連結

    else
        return mkpr(2 * n + 1, 2 * n + 1); // あいこです
}

pint e()
{
    return mkpr(-1, -1);
}

int op2(int a, int b)
{
    if (min(a, b) == -1)
        return max(a, b);
    else if (a == b)
        return a;
    else
        return n;
}

int e2()
{
    return -1;
}

int main()
{
    cin >> n >> m;
    segtree<pint, op, e> seg(m);
    segtree<int, op2, e2> seg2(m);
    for (int i = 0; i < m; i++)
    {
        int a;
        cin >> a;
        seg.set(i, mkpr(a, a));
        seg2.set(i, a);
    }
    int Q;
    cin >> Q;
    int x = 0, y = 0, res = 0;
    for (int i = 0; i < Q; i++)
    {
        int v, w;
        cin >> v >> w;
        if (res)
        {
            x = v - x;
            y = w - y;
        }
        else
        {
            x = v + x;
            y = w + y;
        }
        x = (x + m) % m;
        y = (y + m) % m;

        if (x > y)
        {
            int z = x;
            x = y;
            y = z;
        }
        y += 1;
        pint ret = seg.prod(x, y);
        int ret2 = seg2.prod(x, y);
        if (ret.first == 2 * n + 1 || ret2 != n || (ret.second - ret.first + (2 * n + 1)) % (2 * n + 1) > n)
        {
            cout << "Aiko" << endl;
            res = 1;
            x = v;
            y = w;
        }
        else
        {
            cout << "Shoubu Ari" << endl;
            res = 0;
            x = v;
            y = w;
        }
    }
}

Comments

There are no comments at the moment.