WC 第一课堂讲字符串哈希和快速幂?
第一讲堂内容:
上午:
LOJ143. 质数判定
Miller-Rabin 模板。
Fermart 小定理:
若
反之,若
总结:若
二次探测定理:
当
合数情况则不然。称
若
若
Miller-Rabin 素性测试:
首先易证明除
结合 Fermart 小定理与二次探测定理。
注意到绝大部分素数均为奇数,则
构造数列
若
#include <bits/stdc++.h>
#define d(x) cerr << #x << " => " << x << endl
#define dd(x) cerr << #x << endl
#define D cerr << "Passed [" << __FUNCTION__ << "] on line " << __LINE__ << endl
#define ms(x) memset(x, 0, sizeof x)
#define int __int128
using namespace std;
int rd() {
int f = 1, val = 0; char ch = getchar();
while(!isdigit(ch)) f = (ch == '-' ? -1 : 1), ch = getchar();
while(isdigit(ch)) val = val * 10 + ch - '0', ch = getchar();
return f * val;
}
void file() {
freopen("in.in", "r", stdin);
//freopen("out.out", "w+", stdout);
}
int qpow(int a, int b, int m) {
int res = 1, base = a;
while(b) {
if(b & 1) res = base * res % m;
base = base * base % m; b >>= 1;
}
return res;
}
bool MillerRabin(int x) {
if(x == 0 || x == 1) return false;
if(x == 2) return true;
if(x % 2 == 0) return false;
for(int i = 1; i <= 10; i++) {
int it = (((int)rand() << 31) | rand()) % (x - 2) + 2;
int t = (x - 1) / 2;
while(t > 0) {
int res = qpow(it, t, x);
if(res == x - 1) break;
else if(res != 1) return false;
else if(res == 1) {
if(t % 2 == 1) break;
else t /= 2;
}
}
}
return true;
}
signed main() {
#ifdef LOCAL
file();
#endif
unsigned long long x;
while(~scanf("%lld", &x)) {
puts(MillerRabin(x) ? "Y" : "N");
}
return 0;
}
下午:
此处评论已关闭