全都 TLE 啦!!求差错

P4718 【模板】Pollard-Rho

两个 long long 相乘时应转为 __int128 吧?
by MichaelLee @ 2022-08-15 09:57:30


@[MichaelLee](/user/288135) $\texttt{But \ It's \ Still\ TLE}$
by Link_Cut_Y @ 2022-09-14 22:12:41


LL qpow(LL a, LL b, LL p) { LL res = 1; while (b) { if (b & 1) res = res * a % p; a = a * a % p; b >>= 1; } return res; } 这里写挂了,两个long long相乘会溢出,导致米勒罗宾把素数判断成非素数,然后硬上pollard-rho死循环了
by cats142857 @ 2022-09-22 22:15:30


@[cats142857](/user/721928) 全都改成 $int128$ 了,但是还是不对。 ``` #include <iostream> #include <cstring> #include <cstdio> #include <algorithm> #include <cmath> #include <ctime> #define LL __int128 using namespace std; const LL test[] = {2, 3, 5, 7, 11, 13, 17, 19, 23}; LL ans = -0x3f3f3f3f; int T; LL n; namespace Fread { const int SIZE = 1 << 21; char buf[SIZE], *S, *T; inline char getchar() { if (S == T) { T = (S = buf) + fread(buf, 1, SIZE, stdin); if (S == T) return '\n'; } return *S ++ ; } } // namespace Fread namespace Fwrite { const int SIZE = 1 << 21; char buf[SIZE], *S = buf, *T = buf + SIZE; inline void flush() { fwrite(buf, 1, S - buf, stdout); S = buf; } inline void putchar(char c) { *S ++ = c; if (S == T) flush(); } struct NTR { ~ NTR() { flush(); } } ztr; } // namespace Fwrite #ifdef ONLINE_JUDGE #define getchar Fread :: getchar #define putchar Fwrite :: putchar #endif namespace Fastio { struct Reader { template<typename T> Reader& operator >> (T& x) { char c = getchar(); T f = 1; while (c < '0' || c > '9') { if (c == '-') f = -1; c = getchar(); } x = 0; while (c >= '0' && c <= '9') { x = x * 10 + (c - '0'); c = getchar(); } x *= f; return *this; } Reader& operator >> (char& c) { c = getchar(); while (c == ' ' || c == '\n') c = getchar(); return *this; } Reader& operator >> (char* str) { int len = 0; char c = getchar(); while (c == ' ' || c == '\n') c = getchar(); while (c != ' ' && c != '\n' && c != '\r') { str[len++] = c; c = getchar(); } str[len] = '\0'; return *this; } Reader(){} } cin; const char endl = '\n'; struct Writer { template<typename T> Writer& operator << (T x) { if (x == 0) { putchar('0'); return *this; } if (x < 0) { putchar('-'); x = -x; } static int sta[45]; int top = 0; while (x) { sta[++top] = x % 10; x /= 10; } while (top) { putchar(sta[top] + '0'); --top; } return *this; } Writer& operator << (char c) { putchar(c); return *this; } Writer& operator << (char* str) { int cur = 0; while (str[cur]) putchar(str[cur++]); return *this; } Writer& operator << (const char* str) { int cur = 0; while (str[cur]) putchar(str[cur++]); return *this; } Writer(){} } cout; } // namespace Fastio #define cin Fastio :: cin #define cout Fastio :: cout #define endl Fastio :: endl namespace Functions { LL abs(LL x) { return x < 0 ? -x : x; } LL gcd(LL a, LL b) { return !b ? a : gcd(b, a % b); } LL qpow(LL a, LL b, LL p) { LL res = 1; while (b) { if (b & 1) res = res * a % p; a = a * a % p; b >>= 1; } return res; } LL mul(LL a, LL b, LL p) { LL res = 0; while (b) { if (b & 1) res = (res + a) % p; a = (a + a) % p; b >>= 1; } return res; } bool Miller_Rabin(LL n) { // ÅÐ¶Ï n ÊÇ·ñÊÇÖÊÊý if (n == 1) return false; LL t = n - 1, k = 0; while (!(t & 1)) t >>= 1, k ++ ; for (int i = 0; i < 9; i ++ ) { if (n == test[i]) return true; LL a = qpow(test[i], t, n), ne = a; for (int i = 1; i <= k; i ++ ) { ne = a * a % n; if (ne == 1 && a != 1 && a != n - 1) return false; a = ne; } if (a != 1) return false; } return true; } } using namespace Functions; LL Pollard_Rho(LL n) { // ·Ö½â n if (n == 4) return 2; if (Miller_Rabin(n)) return n; LL c = rand() % (n - 1) + 1; auto f = [=](LL x) {return (mul(x, x, n) + c) % n; }; LL x = f(c), y = f(f(c)); for (int lim = 1; x != y; lim = min(lim << 1, 128)) { LL cnt = 1; for (int i = 0; i < lim; i ++ ) { cnt = mul(cnt, abs((x - y) % n), n); if (!cnt) break; x = f(x), y = f(f(y)); } if (gcd(cnt, n) != 1) return gcd(cnt, n); } return n; } void max_factor(LL n) { if (Miller_Rabin(n)) return ans = max(ans, n), void(); LL d = Pollard_Rho(n); while (d == n) d = Pollard_Rho(n); if (Miller_Rabin(d)) ans = max(ans, d); else max_factor(d); d = n / d; if (Miller_Rabin(d)) ans = max(ans, d); else max_factor(d); } int main() { srand(time(0)); cin >> T; while (T -- ) { cin >> n; ans = -0x3f3f3f3fll; if (Miller_Rabin(n)) puts("Prime"); else max_factor(n), cout << ans << endl; } return 0; } ```
by Link_Cut_Y @ 2022-10-30 12:25:41


|