#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; const unsigned char mask2per8 = 0x55; class PrimeBitMask { public: PrimeBitMask(unsigned int aLimit, unsigned int aLowerLimit); ~PrimeBitMask(); bool isPrime(unsigned int aNum); protected: inline void clearBitPos(unsigned int aPos); void setBitPos(unsigned int aPos); void clearMultiples(unsigned int aUpperLimitBitPos, bool aWithLoverLimit = false); protected: const unsigned int m_limit; const unsigned int m_loverLimit; unsigned int m_byteLength; unsigned int m_nextPrime; vector m_mask; }; PrimeBitMask::PrimeBitMask(unsigned int aLimit, unsigned int aLowerLimit) : m_limit(aLimit) , m_loverLimit(aLowerLimit) , m_nextPrime(3) , m_byteLength(aLimit / 8 + ((aLimit % 8) ? 1 : 0)) , m_mask(m_byteLength, mask2per8) { if (m_mask.size() == m_byteLength) { unsigned int maxRelPrimeLimit = (unsigned int)ceil(sqrt(m_limit)); while (m_nextPrime < m_limit / m_nextPrime) { clearMultiples(maxRelPrimeLimit); for (unsigned int i = m_nextPrime + 2; i <= m_limit; i += 2) { if (isPrime(i)) { m_nextPrime = i; break; } } } m_nextPrime = 3; while (m_nextPrime < m_limit / m_nextPrime) { clearMultiples(m_limit, true); for (unsigned int i = m_nextPrime + 2; i <= m_limit; i += 2) { if (isPrime(i)) { m_nextPrime = i; break; } } } clearBitPos(0); // 1 is not a prime setBitPos(1); // 2 is a prime } } PrimeBitMask::~PrimeBitMask() { m_mask.clear(); } void PrimeBitMask::clearBitPos(unsigned int aPos) { int bitPos = aPos % 8; // 0 ... 7 unsigned int offset = aPos / 8; unsigned char mask = (1 << bitPos) ^ 0xFF; m_mask[offset] &= mask; } void PrimeBitMask::setBitPos(unsigned int aPos) { int bitPos = aPos % 8; // 0 ... 7 unsigned int offset = aPos / 8; unsigned char mask = (1 << bitPos); m_mask[offset] |= mask; } void PrimeBitMask::clearMultiples(unsigned int aUpperLimitBitPos, bool aWithLoverLimit) { unsigned int pos = m_nextPrime * m_nextPrime - 1; if (pos >= aUpperLimitBitPos) { return; } if (aWithLoverLimit && m_loverLimit - 1 > pos) { unsigned int multiplicator = m_loverLimit / m_nextPrime + (m_loverLimit % m_nextPrime ? 1 : 0); pos = multiplicator * m_nextPrime - 1; } unsigned int stepLength = m_nextPrime; unsigned int stepByte = stepLength / 8; unsigned int stepBit = stepLength % 8; unsigned int posByte = pos / 8; unsigned int posBit = pos % 8; unsigned int stepNum = (aUpperLimitBitPos - pos) / stepLength + ((aUpperLimitBitPos - pos) % stepLength ? 1 : 0); unsigned char * checkPtr = &m_mask[posByte]; unsigned char checkByte = *checkPtr; while (stepNum) { if (checkByte) { unsigned char mask = (1 << posBit); if (checkByte & mask) { *checkPtr &= mask ^ 0xFF; } } posByte += stepByte; posBit += stepBit; if (posBit / 8) { posByte++; posBit -= 8; } stepNum--; if (stepNum) { checkPtr = &m_mask[posByte]; checkByte = *checkPtr; } } } bool PrimeBitMask::isPrime(unsigned int aNum) { bool ret = false; if (--aNum > 0 && aNum < m_limit) { unsigned int offsetByte = m_mask[aNum / 8]; if (offsetByte) { int bitPos = aNum % 8; unsigned char mask = (1 << bitPos); ret = ((offsetByte & mask) == mask); } } return ret; } int main() { PrimeBitMask pbm(100000, 1); int g; cin >> g; for (int a0 = 0; a0 < g; a0++) { unsigned int n; cin >> n; // your code goes here int primes = 0; for (unsigned int i = 2; i <= n; ++i) { if (pbm.isPrime(i)) { ++primes; } } if (0 == primes % 2) { cout << "Bob" << endl; } else { cout << "Alice" << endl; } } return 0; }