Cod sursa(job #3153116)

Utilizator PescarusTanislav Luca Andrei Pescarus Data 28 septembrie 2023 11:03:35
Problema GFact Scor 80
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.77 kb
// #include <iostream>
// #include <fstream>

// using namespace std;
// ifstream f("gfact.in");
// ofstream g("gfact.out");




// int legendre(int a, int p){
//     int nr = 0, putere = p;
//     while(putere <= a){
//         nr += a / putere;
//         putere *= p;
//     }
//     return nr;
// }

// int factorial(int p, int q){
//     //merg din p in p
//     long long st = 1, dr = q, sol = 0;

//     while(st <= dr){
//         long long mid = (st + dr) / 2;  
//         if(legendre(mid * p, p) >= q){
//             dr = mid - 1;
//             sol = mid;
//         } 
//         else{
//             st = mid + 1;
//         }
//     }
//     return sol * p;
// }

// int main(){
//     int p, q, sol = 0;
//     f >> p >> q;
//     int putere = 0;
//     while(p % 2 == 0){
//         p /= 2;
//         putere++;
//     }
//     if(putere > 0){
//         sol = max(sol, factorial(2, q * putere));
//     }
//     for(int i = 3; i * i <= p; i += 2){
//         putere = 0;

//         while(p % i == 0){
//             p /= i;
//             putere++;
//         }
//         if(putere > 0){
//              sol = max(sol, factorial(i, putere * q));
//         }
       
//     }
//     g << sol << '\n';
// }
//mai intai m-am gandit problema ca o problema mai simpla adica P sa fie numar prim 
// am folosit formula lui Legendre
//dupa am reusit sa fac porblema toata
//si am cautat solutia binar
//si am facut niste optimizarti pe ici si colo

#include <iostream>
#include <algorithm>
#include <fstream>
using namespace std;
ifstream f("gfact.in");
ofstream g("gfact.out");

int formulaluiLegrendre(int B, int P){
    int putere = P, cnt =0;
      while(putere <= B){
        cnt+= B/putere;
        putere*=P;
      }
      return cnt;
}

int cautarebinara(int p, int q){
    long long left=1, right = q;
    long long sol = 0 ;

    while(left<= right){
      long long mid = (left+right)/2;
      if(formulaluiLegrendre(mid*p, p) >= q){
          sol = mid;
          right = mid - 1;
      }
      else {
        left = mid + 1;
      }
    }
    return sol*p;
}
int main(){
    int  P, Q;
    f>>P>>Q;
    int sol=0;
  //  int d=2;
    int putere = 0;
    while(P % 2 == 0){
        putere++;
        P /= 2;
    }
    if(putere > 0){
        sol = max(sol, cautarebinara(2, Q * putere));
    }
    if(P != 1){
        for(int i = 3; i * i <= P; i += 2){
            putere = 0;
            while(P % i == 0){
                P /= i;
                putere ++ ;
            }
            if(putere > 0){
                sol = max(sol, cautarebinara(i, Q * putere));
            }
        }
    }
    if(P > 1){
        sol = cautarebinara(P, Q);
    }
    
    g << sol;
}