canuc80k5607·8/20

Nhận Diện Số Nguyên Tố

Nộp bài trên LQDOJ

Bài 56 · Randomized Algorithms

Bạn được cho nhiều số nguyên dương. Với mỗi số , hãy xác định có phải là số nguyên tố hay không.

Một số nguyên lớn hơn được gọi là số nguyên tố nếu nó chỉ có đúng hai ước dương là và chính nó.

Input

  • Dòng đầu chứa số nguyên - số bộ test.
  • Mỗi dòng trong dòng tiếp theo chứa một số nguyên .

Output

  • Với mỗi bộ test, in trên một dòng:
  • YES nếu là số nguyên tố;
  • NO nếu không phải số nguyên tố.

Constraints

  • .
  • .

Scoring

  • Subtask ( số điểm): trong mọi bộ test.
  • Subtask ( 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: và là số nguyên tố; , còn chia hết cho , 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: {2, 325, 9375, 28178, 450775, 9780504, 1795265022}.
  • Ý 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ụ.