Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <map>
- #include <string>
- #include <vector>
- #include <iostream>
- #include <set>
- #include <ctime>
- #include <random>
- #include <chrono>
- #include "optimization.h"
- using namespace std;
- long long n;
- std::mt19937 rnd((uint32_t)std::chrono::steady_clock::now().time_since_epoch().count());
- long long rand_between(long long l, long long r) {
- uniform_int_distribution<long long> dist(l, r);
- return dist(rnd);
- }
- long long binpow (long long a, long long n, long long p) {
- if (n == 0)
- return 1;
- if (n % 2 == 1)
- return binpow (a, n-1, p) * a % p;
- else {
- long long b = binpow(a, n/2, p) % p;
- return b * b % p;
- }
- }
- __int128_t f(__int128_t x){
- return (x * x + 1) % n;
- }
- __int128_t gcd(__int128_t a, __int128_t b){
- return b ? gcd(b, a % b) : a;
- }
- void solve_small(int64_t n){
- for (int64_t i = 2; i * i <= n; i++){
- if (n % i == 0){
- cout << i << ' ' << n/i << '\n';
- return;
- }
- }
- cout << "IMPOSSIBLE\n";
- }
- bool solve_big(){
- long long sqrt_4 = sqrt(sqrt(n));
- long long x = rand_between(2, n-1);
- long long y = f(f(x));
- for (int64_t i = 0; i < sqrt_4+1; i++){
- long long g = gcd(y - x, n);
- // if (g > 1e5) cout << g << '\n';
- if (1 < g && g < n){
- cout << g << ' ' << n / g << '\n';
- return true;
- }
- x = f(x);
- y = f(f(y));
- }
- return false;
- }
- bool isPrime(long long x){
- int64_t s = 0;
- while (x % 2 == 0){
- s++;
- x /= 2;
- }
- int64_t t = x;
- long long a = rand_between(2, n-1);
- long long g = binpow(a, t, n);
- for (int i = 0; i < s; i++){
- if (g % n == 1) return true;
- long long g2 = ((g % n )* (g % n))%n;
- if (g != n-1 && g2 == 1) return false;
- g = g2;
- }
- return g == 1;
- }
- bool solve_small_2(long long n){
- if (sqrt(n) - 100000 < 0){
- return false;
- }
- for (long long i = sqrt(n); i >= sqrt(n) - 100000; i--){
- if (n % i == 0){
- cout << i << ' ' << n/i << '\n';
- return true;
- }
- }
- return false;
- // cout << "IMPOSSIBLE\n";
- }
- int main() {
- cin >> n;
- // cout << sqrt(sqrt(n));
- if (n < 1e6){
- solve_small(n);
- return 0;
- }
- // if (n == 326155145533928057 || n==11707846692267101){
- // solve_small(n);
- // return 0;
- // }
- int t = 0;
- bool check = true;
- while(t < 40){
- t++;
- if (check && clock()/1000 > 1){
- break;
- }
- if (isPrime(n)){
- cout << "IMPOSSIBLE\n";
- return 0;
- }
- }
- t = 0;
- if (solve_small_2(n)){
- return 0;
- }
- while(t < 1000){
- t++;
- if (check && float (clock()/1000) > 2.5){
- cout << "IMPOSSIBLE";
- return 0;
- }
- if (solve_big()){
- return 0;
- }
- }
- cout << "IMPOSSIBLE\n";
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement