QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#463029#249. Miller Rabin 算法NOI_AK_ME#Compile Error//C++1418.2kb2024-07-04 11:39:432024-07-04 11:39:43

Judging History

你现在查看的是最新测评结果

  • [2024-07-04 11:39:43]
  • 评测
  • [2024-07-04 11:39:43]
  • 提交

answer

#include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <climits>
#include <cmath>
#include <functional>
#include <iostream>
#include <limits>
#include <list>
#include <map>
#include <memory>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <stack>
#include <cstring>
#include <unordered_map>
#include <unordered_set>
#if defined(_WIN32)
#include <windows.h>
#include <psapi.h>
#else
#include "sys/time.h"
#endif
namespace OY {
#define cin OY::inputHelper<1024, 20>::getInstance()
#define getchar() ({char c=cin.getChar_Checked();cin.next();c;})
#define cout OY::outputHelper<1048576>::getInstance()
#define putchar cout.putChar
#define endl '\n'
#define putlog(...) OY::printLog(", ", __VA_ARGS__)
template <uint64_t _BufferSize = 1024, uint64_t _BlockSize = 20>
class inputHelper {
    FILE *m_filePtr;
    char m_buf[_BufferSize], *m_end, *m_cursor;
    bool m_ok;
    void flush() {
        uint64_t a = m_end - m_cursor;

        if (a >= _BlockSize)
            return;

        memmove(m_buf, m_cursor, a);
        uint64_t b = fread(m_buf + a, 1, _BufferSize - a, m_filePtr);
        m_cursor = m_buf;

        if (a + b < _BufferSize) {
            m_end = m_buf + a + b;
            *m_end = EOF;
        }
    }

public:
    explicit inputHelper(const char *inputFileName) : m_ok(true) {
        if (!*inputFileName)
            m_filePtr = stdin;
        else
            m_filePtr = fopen(inputFileName, "rt");

        m_end = m_cursor = m_buf + _BufferSize;
    }
    ~inputHelper() {
        fclose(m_filePtr);
    }
    static inputHelper<_BufferSize, _BlockSize> &getInstance() {
#ifdef OY_LOCAL
        static inputHelper<_BufferSize, _BlockSize> s_obj("in.txt");
#else
        static inputHelper<_BufferSize, _BlockSize> s_obj("");
#endif
        return s_obj;
    }
    static constexpr bool isBlank(char c) {
        return c == ' ' || c == '\t' || c == '\n' || c == '\r';
    }
    static constexpr bool isEndline(char c) {
        return c == '\n' || c == EOF;
    }
    const char &getChar_Checked() {
        if (m_cursor < m_end)
            return *m_cursor;

        uint64_t b = fread(m_buf, 1, _BufferSize, m_filePtr);
        m_cursor = m_buf;

        if (b < _BufferSize) {
            m_end = m_buf + b;
            *m_end = EOF;
        }

        return *m_cursor;
    }
    const char &getChar_Unchecked() const {
        return *m_cursor;
    }
    void next() {
        ++m_cursor;
    }
    void setState(bool _ok) {
        m_ok = _ok;
    }
    template <typename _Tp, std::enable_if_t<std::is_signed_v<_Tp> & std::is_integral_v<_Tp>> * = nullptr>
    inputHelper<_BufferSize, _BlockSize> &operator>>(_Tp &ret) {
        while (isBlank(getChar_Checked()))
            next();

        flush();

        if (getChar_Unchecked() == '-') {
            next();

            if (isdigit(getChar_Unchecked())) {
                ret = -(getChar_Unchecked() - '0');

                while (next(), isdigit(getChar_Unchecked()))
                    ret = ret * 10 - (getChar_Unchecked() - '0');
            } else
                m_ok = false;
        } else {
            if (isdigit(getChar_Unchecked())) {
                ret = getChar_Unchecked() - '0';

                while (next(), isdigit(getChar_Unchecked()))
                    ret = ret * 10 + (getChar_Unchecked() - '0');
            } else
                m_ok = false;
        }

        return *this;
    }
    template <typename _Tp, std::enable_if_t<std::is_unsigned_v<_Tp> & std::is_integral_v<_Tp>> * = nullptr>
    inputHelper<_BufferSize, _BlockSize> &operator>>(_Tp &ret) {
        while (isBlank(getChar_Checked()))
            next();

        flush();

        if (isdigit(getChar_Unchecked())) {
            ret = getChar_Unchecked() - '0';

            while (next(), isdigit(getChar_Unchecked()))
                ret = ret * 10 + (getChar_Unchecked() - '0');
        } else
            m_ok = false;

        return *this;
    }
    template <typename _Tp, std::enable_if_t<std::is_floating_point_v<_Tp>> * = nullptr>
    inputHelper<_BufferSize, _BlockSize> &operator>>(_Tp &ret) {
        bool neg = false, integer = false, decimal = false;

        while (isBlank(getChar_Checked()))
            next();

        flush();

        if (getChar_Unchecked() == '-') {
            neg = true;
            next();
        }

        if (!isdigit(getChar_Unchecked()) && getChar_Unchecked() != '.') {
            m_ok = false;
            return *this;
        }

        if (isdigit(getChar_Unchecked())) {
            integer = true;
            ret = getChar_Unchecked() - '0';

            while (next(), isdigit(getChar_Unchecked()))
                ret = ret * 10 + (getChar_Unchecked() - '0');
        }

        if (getChar_Unchecked() == '.') {
            next();

            if (isdigit(getChar_Unchecked())) {
                if (!integer)
                    ret = 0;

                decimal = true;
                _Tp unit = 0.1;
                ret += unit * (getChar_Unchecked() - '0');

                while (next(), isdigit(getChar_Unchecked())) {
                    unit *= 0.1;
                    ret += unit * (getChar_Unchecked() - '0');
                }
            }
        }

        if (!integer && !decimal)
            m_ok = false;
        else if (neg)
            ret = -ret;

        return *this;
    }
    inputHelper<_BufferSize, _BlockSize> &operator>>(char &ret) {
        while (isBlank(getChar_Checked()))
            next();

        ret = getChar_Checked();
        next();
        return *this;
    }
    inputHelper<_BufferSize, _BlockSize> &operator>>(std::string &ret) {
        while (isBlank(getChar_Checked()))
            next();

        if (getChar_Checked() != EOF) {
            ret.clear();

            do {
                ret += getChar_Checked();
                next();
            } while (!isBlank(getChar_Checked()) && getChar_Unchecked() != EOF);
        } else
            m_ok = false;

        return *this;
    }
    explicit operator bool() {
        return m_ok;
    }
};
template <uint64_t _BufferSize = 1048576>
class outputHelper {
    FILE *m_filePtr = nullptr;
    char m_buf[_BufferSize], *m_end, *m_cursor;
    char m_tempBuf[50], *m_tempBufCursor, *m_tempBufDot;
    uint64_t m_floatReserve, m_floatRatio;

public:
    outputHelper(const char *outputFileName, int prec = 6) : m_end(m_buf + _BufferSize) {
        if (!*outputFileName)
            m_filePtr = stdout;
        else
            m_filePtr = fopen(outputFileName, "wt");

        m_cursor = m_buf;
        m_tempBufCursor = m_tempBuf;
        precision(prec);
    }
    static outputHelper<_BufferSize> &getInstance() {
#ifdef OY_LOCAL
        static outputHelper<_BufferSize> s_obj("out.txt");
#else
        static outputHelper<_BufferSize> s_obj("");
#endif
        return s_obj;
    }
    ~outputHelper() {
        flush();
        fclose(m_filePtr);
    }
    void precision(int prec) {
        m_floatReserve = prec;
        m_floatRatio = pow(10, prec);
        m_tempBufDot = m_tempBuf + prec;
    }
    outputHelper<_BufferSize> &flush() {
        fwrite(m_buf, 1, m_cursor - m_buf, m_filePtr);
        fflush(m_filePtr);
        m_cursor = m_buf;
        return *this;
    }
    void putChar(const char &c) {
        if (m_cursor == m_end)
            flush();

        *m_cursor++ = c;
    }
    void putS(const char *c) {
        while (*c)
            putChar(*c++);
    }
    template <typename _Tp, std::enable_if_t<std::is_signed_v<_Tp> & std::is_integral_v<_Tp>> * = nullptr>
    outputHelper<_BufferSize> &operator<<(const _Tp &ret) {
        _Tp _ret = _Tp(ret);

        if (_ret >= 0) {
            do {
                *m_tempBufCursor++ = '0' + _ret % 10;
                _ret /= 10;
            } while (_ret);

            do
                putChar(*--m_tempBufCursor);

            while (m_tempBufCursor > m_tempBuf);
        } else {
            putChar('-');

            do {
                *m_tempBufCursor++ = '0' - _ret % 10;
                _ret /= 10;
            } while (_ret);

            do
                putChar(*--m_tempBufCursor);

            while (m_tempBufCursor > m_tempBuf);
        }

        return *this;
    }
    template <typename _Tp, std::enable_if_t<std::is_unsigned_v<_Tp> & std::is_integral_v<_Tp>> * = nullptr>
    outputHelper<_BufferSize> &operator<<(const _Tp &ret) {
        _Tp _ret = _Tp(ret);

        do {
            *m_tempBufCursor++ = '0' + _ret % 10;
            _ret /= 10;
        } while (_ret);

        do
            putChar(*--m_tempBufCursor);

        while (m_tempBufCursor > m_tempBuf);

        return *this;
    }
    template <typename _Tp, std::enable_if_t<std::is_floating_point_v<_Tp>> * = nullptr>
    outputHelper<_BufferSize> &operator<<(const _Tp &ret) {
        if (ret < 0) {
            putChar('-');
            return *this << -ret;
        }

        _Tp _ret = ret * m_floatRatio;
        uint64_t integer = _ret;

        if (_ret - integer >= 0.4999999999)
            integer++;

        do {
            *m_tempBufCursor++ = '0' + integer % 10;
            integer /= 10;
        } while (integer);

        if (m_tempBufCursor > m_tempBufDot) {
            do
                putChar(*--m_tempBufCursor);

            while (m_tempBufCursor > m_tempBufDot);

            putChar('.');
        } else {
            putS("0.");

            for (int i = m_tempBufDot - m_tempBufCursor; i--;)
                putChar('0');
        }

        do
            putChar(*--m_tempBufCursor);

        while (m_tempBufCursor > m_tempBuf);

        return *this;
    }
    outputHelper<_BufferSize> &operator<<(const char &ret) {
        putChar(ret);
        return *this;
    }
    outputHelper<_BufferSize> &operator<<(const std::string &ret) {
        putS(ret.data());
        return *this;
    }
};
template <uint64_t _BufferSize, uint64_t _BlockSize>
inputHelper<_BufferSize, _BlockSize> &getline(inputHelper<_BufferSize, _BlockSize> &ih, std::string &ret) {
    ret.clear();

    if (ih.getChar_Checked() == EOF)
        ih.setState(0);
    else {
        while (!inputHelper<_BufferSize, _BlockSize>::isEndline(ih.getChar_Checked())) {
            ret += ih.getChar_Unchecked();
            ih.next();
        }

        ih.next();
    }

    return ih;
}
template <typename D, typename T, typename... S>
void printLog(D delim, const T &x, S... rest) {
    cout << x;

    if constexpr(sizeof...(rest) > 0) {
        cout << delim;
        printLog(delim, rest...);
    }
}
}
using OY::getline;
namespace OY {
template <typename _ModType>
struct Barrett {
    _ModType m_P;
    __uint128_t m_Pinv;
    constexpr Barrett() = default;
    constexpr explicit Barrett(_ModType __P) : m_P(__P), m_Pinv(-uint64_t(__P) / __P + 1) {}
    constexpr _ModType mod() const {
        return m_P;
    }
    constexpr _ModType mod(uint64_t __a) const {
        __a -= uint64_t(m_Pinv * __a >> 64) * m_P + m_P;

        if (__a >= m_P)
            __a += m_P;

        return __a;
    }
    constexpr _ModType raw_mod(uint64_t __a) const {
        return __a % m_P;
    }
    constexpr _ModType multiply(uint64_t __a, uint64_t __b) const {
        return mod(__a * __b);
    }
    constexpr _ModType multiply_128(uint64_t __a, uint64_t __b) const {
        if (__builtin_clzll(__a) + __builtin_clzll(__b) >= 64)
            return multiply(__a, __b);

        return __uint128_t(__a) * __b % m_P;
    }
    constexpr _ModType multiply_ld(uint64_t __a, uint64_t __b) const {
        if (__builtin_clzll(__a) + __builtin_clzll(__b) >= 64)
            return multiply(__a, __b);

        int64_t res = __a * __b - uint64_t(1.L / m_P * __a * __b) * m_P;

        if (res < 0)
            res += m_P;
        else if (res >= m_P)
            res -= m_P;

        return res;
    }
    constexpr _ModType pow(uint64_t __a, uint64_t __n) const {
        _ModType res = 1, b = mod(__a);

        while (__n) {
            if (__n & 1)
                res = multiply(res, b);

            b = multiply(b, b);
            __n >>= 1;
        }

        return res;
    }
    constexpr _ModType pow_128(uint64_t __a, uint64_t __n) const {
        _ModType res = 1, b = mod(__a);

        while (__n) {
            if (__n & 1)
                res = multiply_128(res, b);

            b = multiply_128(b, b);
            __n >>= 1;
        }

        return res;
    }
    constexpr _ModType pow_ld(uint64_t __a, uint64_t __n) const {
        _ModType res = 1, b = mod(__a);

        while (__n) {
            if (__n & 1)
                res = multiply_ld(res, b);

            b = multiply_ld(b, b);
            __n >>= 1;
        }

        return res;
    }
    template <typename _Tp>
    constexpr _Tp divide(_Tp __a) const {
        if (__a < m_P)
            return 0;

        _Tp res = m_Pinv * __a >> 64;

        if (__a - res * m_P >= m_P)
            res++;

        return res;
    }
    template <typename _Tp>
    constexpr std::pair<_Tp, _Tp> divmod(_Tp __a) const {
        _Tp quo = (__a * m_Pinv) >> 64, rem = __a - quo * m_P;

        if (rem >= m_P) {
            quo++;
            rem -= m_P;
        }

        return {quo, rem};
    }
};
using Barrett32 = Barrett<uint32_t>;
using Barrett64 = Barrett<uint64_t>;
}
namespace OY {
template <typename _ModType>
struct _MontgomeryTag;
template <>
struct _MontgomeryTag<uint32_t> {
    using long_type = uint64_t;
    static constexpr uint32_t limit = (1073741824u) - 1;
    static constexpr uint32_t inv_loop = 4;
    static constexpr uint32_t length = 32;
};
template <>
struct _MontgomeryTag<uint64_t> {
    using long_type = __uint128_t;
    static constexpr uint64_t limit = (1ull << 63) - 1;
    static constexpr uint32_t inv_loop = 5;
    static constexpr uint32_t length = 64;
};
template <typename _ModType>
struct Montgomery {
    using _FastType = _ModType;
    using _LongType = typename _MontgomeryTag<_ModType>::long_type;
    _ModType m_P;
    _ModType m_Pinv;
    _ModType m_Ninv;
    Barrett<_ModType> m_brt;
    constexpr Montgomery() = default;
    constexpr explicit Montgomery(_ModType __P) : m_P(__P), m_Pinv(__P), m_Ninv(-_LongType(__P) % __P),
        m_brt(__P) {
        assert((__P & 1) && __P > 1 && __P <= _MontgomeryTag<_ModType>::limit);

        for (uint32_t i = 0; i < _MontgomeryTag<_ModType>::inv_loop; i++)
            m_Pinv *= _ModType(2) - __P * m_Pinv;
    }
    constexpr _ModType mod() const {
        return m_brt.mod();
    }
    constexpr _ModType mod(uint64_t __a) const {
        return m_brt.mod(__a);
    }
    constexpr _ModType raw_mod(uint64_t __a) const {
        return m_brt.raw_mod(__a);
    }
    constexpr _FastType init(uint64_t __a) const {
        return reduce(_LongType(mod(__a)) * m_Ninv);
    }
    constexpr _FastType raw_init(uint64_t __a) const {
        return reduce(_LongType(raw_mod(__a)) * m_Ninv);
    }
    constexpr _FastType reduce(_LongType __a) const {
        _FastType res = (__a >> _MontgomeryTag<_ModType>::length) - _ModType(_LongType(_ModType(
                            __a) * m_Pinv) * m_P >> _MontgomeryTag<_ModType>::length);

        if (res >= mod())
            res += mod();

        return res;
    }
    constexpr _ModType reduce(_FastType __a) const {
        _ModType res = -_ModType(_LongType(__a * m_Pinv) * m_P >> _MontgomeryTag<_ModType>::length);

        if (res >= mod())
            res += mod();

        return res;
    }
    constexpr _FastType multiply(_FastType __a, _FastType __b) const {
        return reduce(_LongType(__a) * __b);
    }
    constexpr _FastType pow(_FastType __a, uint64_t __n) const {
        _FastType res = reduce(_LongType(1) * m_Ninv);

        while (__n) {
            if (__n & 1)
                res = multiply(res, __a);

            __a = multiply(__a, __a);
            __n >>= 1;
        }

        return res;
    }
    template <typename _Tp>
    constexpr _Tp divide(_Tp __a) const {
        return m_brt.divide(__a);
    }
    template <typename _Tp>
    constexpr std::pair<_Tp, _Tp> divmod(_Tp __a) const {
        return m_brt.divmod(__a);
    }
};
using Montgomery32 = Montgomery<uint32_t>;
using Montgomery64 = Montgomery<uint64_t>;
}
namespace OY {
template <typename _Elem>
constexpr bool isPrime(_Elem n) {
    if (std::is_same_v<_Elem, uint32_t> || n <= UINT32_MAX) {
        if (n <= 1)
            return false;

        if (n == 2 || n == 7 || n == 61)
            return true;

        if (n % 2 == 0)
            return false;

        Barrett32 brt(n);
        uint32_t d = (n - 1) >> __builtin_ctz(n - 1);

        for (auto &&a : {
                    2, 7, 61
                }) {
            uint32_t s = d, y = brt.pow(a, s);

            while (s != n - 1 && y != 1 && y != n - 1) {
                y = brt.multiply(y, y);
                s <<= 1;
            }

            if (y != n - 1 && s % 2 == 0)
                return false;
        }
        return true;
    } else {
        // assert(n < 1ull < 63);
        if (n % 2 == 0)
            return false;

        Montgomery64 mg(n);
        uint64_t d = (n - 1) >> __builtin_ctzll(n - 1), one = mg.init(1);

        for (auto &&a : {
                    2, 325, 9375, 28178, 450775, 9780504, 1795265022
                }) {
            uint64_t s = d, y = mg.pow(mg.init(a), s), t = mg.init(n - 1);

            while (s != n - 1 && y != one && y != t) {
                y = mg.multiply(y, y);
                s <<= 1;
            }

            if (y != t && s % 2 == 0)
                return false;
        }
        return true;
    }
}
constexpr auto isPrime32 = isPrime<uint32_t>;
constexpr auto isPrime64 = isPrime<uint64_t>;
}
int main() {
    uint64_t x;

    while (cin >> x && x) {
        if (OY::isPrime(x))
            cout << "Y";
        else
            cout << "N";

        cout << endl;
    }
}

Details

answer.code:105:51: error: ‘is_signed_v’ is not a member of ‘std’; did you mean ‘is_signed’?
  105 |     template <typename _Tp, std::enable_if_t<std::is_signed_v<_Tp> & std::is_integral_v<_Tp>> * = nullptr>
      |                                                   ^~~~~~~~~~~
      |                                                   is_signed
answer.code:105:51: error: ‘is_signed_v’ is not a member of ‘std’; did you mean ‘is_signed’?
  105 |     template <typename _Tp, std::enable_if_t<std::is_signed_v<_Tp> & std::is_integral_v<_Tp>> * = nullptr>
      |                                                   ^~~~~~~~~~~
      |                                                   is_signed
answer.code:105:66: error: template argument 1 is invalid
  105 |     template <typename _Tp, std::enable_if_t<std::is_signed_v<_Tp> & std::is_integral_v<_Tp>> * = nullptr>
      |                                                                  ^
answer.code:105:70: error: expected ‘>’
  105 |     template <typename _Tp, std::enable_if_t<std::is_signed_v<_Tp> & std::is_integral_v<_Tp>> * = nullptr>
      |                                                                      ^~~
answer.code:105:97: error: expected unqualified-id before ‘=’ token
  105 |     template <typename _Tp, std::enable_if_t<std::is_signed_v<_Tp> & std::is_integral_v<_Tp>> * = nullptr>
      |                                                                                                 ^
answer.code:134:51: error: ‘is_unsigned_v’ is not a member of ‘std’; did you mean ‘is_unsigned’?
  134 |     template <typename _Tp, std::enable_if_t<std::is_unsigned_v<_Tp> & std::is_integral_v<_Tp>> * = nullptr>
      |                                                   ^~~~~~~~~~~~~
      |                                                   is_unsigned
answer.code:134:51: error: ‘is_unsigned_v’ is not a member of ‘std’; did you mean ‘is_unsigned’?
  134 |     template <typename _Tp, std::enable_if_t<std::is_unsigned_v<_Tp> & std::is_integral_v<_Tp>> * = nullptr>
      |                                                   ^~~~~~~~~~~~~
      |                                                   is_unsigned
answer.code:134:68: error: template argument 1 is invalid
  134 |     template <typename _Tp, std::enable_if_t<std::is_unsigned_v<_Tp> & std::is_integral_v<_Tp>> * = nullptr>
      |                                                                    ^
answer.code:134:72: error: expected ‘>’
  134 |     template <typename _Tp, std::enable_if_t<std::is_unsigned_v<_Tp> & std::is_integral_v<_Tp>> * = nullptr>
      |                                                                        ^~~
answer.code:134:99: error: expected unqualified-id before ‘=’ token
  134 |     template <typename _Tp, std::enable_if_t<std::is_unsigned_v<_Tp> & std::is_integral_v<_Tp>> * = nullptr>
      |                                                                                                   ^
answer.code:151:51: error: ‘is_floating_point_v’ is not a member of ‘std’; did you mean ‘is_floating_point’?
  151 |     template <typename _Tp, std::enable_if_t<std::is_floating_point_v<_Tp>> * = nullptr>
      |                                                   ^~~~~~~~~~~~~~~~~~~
      |                                                   is_floating_point
answer.code:151:51: error: ‘is_floating_point_v’ is not a member of ‘std’; did you mean ‘is_floating_point’?
  151 |     template <typename _Tp, std::enable_if_t<std::is_floating_point_v<_Tp>> * = nullptr>
      |                                                   ^~~~~~~~~~~~~~~~~~~
      |                                                   is_floating_point
answer.code:151:71: error: template argument 1 is invalid
  151 |     template <typename _Tp, std::enable_if_t<std::is_floating_point_v<_Tp>> * = nullptr>
      |                                                                       ^~~
answer.code:151:79: error: expected unqualified-id before ‘=’ token
  151 |     template <typename _Tp, std::enable_if_t<std::is_floating_point_v<_Tp>> * = nullptr>
      |                                                                               ^
answer.code:282:51: error: ‘is_signed_v’ is not a member of ‘std’; did you mean ‘is_signed’?
  282 |     template <typename _Tp, std::enable_if_t<std::is_signed_v<_Tp> & std::is_integral_v<_Tp>> * = nullptr>
      |                                                   ^~~~~~~~~~~
      |                                                   is_signed
answer.code:282:51: error: ‘is_signed_v’ is not a member of ‘std’; did you mean ‘is_signed’?
  282 |     template <typename _Tp, std::enable_if_t<std::is_signed_v<_Tp> & std::is_integral_v<_Tp>> * = nullptr>
      |                                                   ^~~~~~~~~~~
      |                                                   is_signed
answer.code:282:66: error: template argument 1 is invalid
  282 |     template <typename _Tp, std::enable_if_t<std::is_signed_v<_Tp> & s...