Bạn được cho nhiều số nguyên dương. Với mỗi số N, hãy xác định N có phải là số nguyên tố hay không.
Một số nguyên lớn hơn 1 được gọi là số nguyên tố nếu nó chỉ có đúng hai ước dương là 1 và chính nó.
Input
Dòng đầu chứa số nguyên t - số bộ test.
Mỗi dòng trong t dòng tiếp theo chứa một số nguyên N.
Output
Với mỗi bộ test, in trên một dòng:
YES nếu N là số nguyên tố;
NO nếu N không phải số nguyên tố.
Constraints
1≤t≤500.
2≤N≤263−1.
Scoring
Subtask 1 (50% số điểm): N≤2⋅106 trong mọi bộ test.
Subtask 2 (50% số điểm): Không có giới hạn bổ sung.
Example
Test 1
Input
6
2
29
91
97
221
1000000
Output
YES
YES
NO
YES
NO
NO
Giải thích: 2,29 và 97 là số nguyên tố; 91=7⋅13,221=13⋅17, còn 1000000 chia hết cho 2, nên ba số đó nhận kết quả NO.
Lời giải tóm tắt
Ý tưởng: Với một số lẻ n > 2, viết
Ý tưởng:n - 1 = d · 2^s, trong đó d là số lẻ.
Ý tưởng: Với một cơ sở a, tính x = a^d mod n. Cơ sở này không chứng minh được n là hợp số nếu x = 1, x = n - 1, hoặc sau một số lần bình phương liên tiếp x đạt n - 1. Ngược lại, a là một nhân chứng chắc chắn rằng n là hợp số. Đó là phép thử Miller-Rabin.
Ý tưởng: Trong dạng ngẫu nhiên, ta chọn nhiều cơ sở độc lập để làm xác suất một hợp số lọt qua giảm rất nhanh. Tuy nhiên, miền của bài bị chặn trong 64 bit. Vì vậy, lời giải dùng tập cơ sở cố định
Ý tưởng: Tập này đủ để Miller-Rabin trở thành phép kiểm tra xác định trên toàn miền số nguyên 64 bit, nên chương trình không có xác suất trả lời sai. Trước đó ta loại nhanh các ước nguyên tố nhỏ.
Ý tưởng: Phép nhân modulo dùng __uint128_t để tính (a·b) mod n mà không tràn khi a, b và n gần 2^63.
Ý tưởng: Mỗi cơ sở cần O(log n) phép nhân modulo. Với số lượng cơ sở cố định, độ phức tạp là O(t log n) thời gian và O(1) bộ nhớ phụ.