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 (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;
- }
- int main() {
- cin >> n;
- if (n < 1e6){
- solve_small(n);
- return 0;
- }
- int t = 0;
- bool check = true;
- while(t < 40){
- t++;
- if (check && (float)clock()/CLOCKS_PER_SEC > 0.01){
- break;
- }
- if (isPrime(n)){
- cout << "IMPOSSIBLE\n";
- return 0;
- }
- }
- t = 0;
- while(t < 1000){
- t++;
- if (check && (float) clock()/CLOCKS_PER_SEC > 0.065){
- cout << "IMPOSSIBLE";
- return 0;
- }
- if (solve_big()){
- return 0;
- }
- }
- cout << "IMPOSSIBLE\n";
- }
Advertisement
Add Comment
Please, Sign In to add comment