hdu 1905 poj3641素数判定与快速幂取余
还是比较简单的,看题目的数据范围,貌似简单判断素数的方法(复杂度sqrt(p))也能过,不过手上有素数测试的模板,就直接用了。秒杀。。。
/* * hdu1905/win.cpp * Created on: 2012-7-12 * Author : ben */ #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <ctime> #include <iostream> #include <algorithm> #include <queue> #include <set> #include <map> #include <stack> #include <string> #include <vector> #include <deque> #include <list> #include <functional> #include <numeric> #include <cctype> using namespace std; typedef long long LL; int modular_exp(int a, int b, int c) { LL res, temp; res = 1 % c, temp = a % c; while (b) { if (b & 1) { res = res * temp % c; } temp = temp * temp % c; b >>= 1; } return (int) res; } int witness(int a, int n) { LL x, d = 1,i = (LL)(ceil(log(n - 1.0) / log(2.0)) - 1); for (; i >= 0; i--) { x = d; d = (d * d) % n; if (d == 1 && x != 1 && x != n - 1) return 1; if (((n - 1) & (1 << i)) > 0) d = (d * a) % n; } return (d == 1 ? 0 : 1); } int miller_rabin(int n, int s = 50) { if (n == 2) return 1; if ((n % 2) == 0) return 0; int j; LL a; for (j = 0; j < s; j++) { // rand()随机产生[0, RAND_MAX)内的整数RAND_MAX=32768 // 直接%n产生不了[RAND_MAX, n)之间的数,使用LL防止乘法溢出 a = (LL)rand() * (n - 2) / RAND_MAX + 1; if (witness(a, n)) return 0; } return 1; } int main() { #ifndef ONLINE_JUDGE freopen("data.in", "r", stdin); #endif int p, a; while(scanf("%d%d", &p, &a) == 2) { if(p == 0 && a == 0) { break; } if(miller_rabin(p)) { puts("no"); continue; } if(modular_exp(a, p, p) == a) { puts("yes"); }else { puts("no"); } } return 0; }