#include<ios> #include<iostream> #include<algorithm> #include<queue> #include<vector> #include<math.h> #include<stdlib.h> #include<stdint.h> #include<inttypes.h> using namespace std; /** N z zadania - limit dla wyniku */ int64_t N; /** Ilosc liczb pierwszych z zadania */ int k; /** Liczby pierwsze z zadania - max 25 w zakresie 2..100 */ int p[30]; /** Funkcja sprwadzajaca, czy zadana liczba mozliwa do zbudowania z liczb pierwszych z zadania */ bool checkIfValid(int64_t val) { if(val==1) return true; for(int i=0;i<k;++i) { while(val%p[i]==0) val/=p[i]; if(val==1) return true; } return false; } /** Proste sprawdzanie dla malych ilosci */ void simpleProcess() { int64_t t=N; for(;;) { if(checkIfValid(t)) { cout<<t<<endl; return; } --t; } } class Calc { public: /** Juz wyliczone liczby */ vector<int64_t> mem; int64_t best=0; void genNext() { int64_t v=mem[mem.size()-1]; while(v>1) { --v; if(checkIfValid(v)) { mem.push_back(v); break; } } } void findFirst() { int maxP=0; int minP=97; for(int i=0;i<k;++i) { if(p[i]>maxP) maxP=p[i]; if(p[i]<minP) minP=p[i]; } int64_t limit=(int64_t)pow(N, 1.0/3); int64_t limit2=limit*(int64_t)minP; // int64_t limit2=limit*(int64_t)3; int64_t v=0; // int l3=max(5000/k, 25); int l3=1610; int cnt=0; //cout<<"Limit: "<<limit<<" Limit2: "<<limit2<<endl; for(int64_t i=limit;v==0 || i<limit2;++i) { if(checkIfValid(i)) { ++cnt; v=i; if(cnt==l3) { //cout<<"CNT Break"<<endl; break; } } } mem.push_back(v); //cout<<"Max val: "<<mem[0]<<endl; } void calc() { for(int i1=0;;++i1) { const int64_t v1=mem[i1]; //cout<<"Processing i1["<<i1<<"]="<<v1<<endl; for(int i2=i1;;++i2) { const int64_t v2=mem[i2]; const int64_t part=v1*v2; bool done=false; if(part>N) { if(i2+1>=mem.size()) genNext(); continue; } const int64_t limit=N/part; if(limit==1) { if(part>best) best=part; break; } for(int i3=i2;;++i3) { if(i3>=mem.size()) genNext(); const int64_t v3=mem[i3]; if(v3<=limit) { int64_t res=part*v3; if(res>best) best=res; if(i3==i1) return; if(i3==i2) done=true; break; } } if(done) break; } } } }; int main(int argc, char** argv) { // przyspiszenie cin/cout ios_base::sync_with_stdio(false); cin.tie(NULL); // odczyt danych cin>>k>>N; for(int i=0;i<k;++i) cin>>p[i]; if(N<10000000) { // proste sprawdzanie simpleProcess(); } else { Calc c; c.findFirst(); c.calc(); cout<<c.best<<endl; } return 0; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 | #include<ios> #include<iostream> #include<algorithm> #include<queue> #include<vector> #include<math.h> #include<stdlib.h> #include<stdint.h> #include<inttypes.h> using namespace std; /** N z zadania - limit dla wyniku */ int64_t N; /** Ilosc liczb pierwszych z zadania */ int k; /** Liczby pierwsze z zadania - max 25 w zakresie 2..100 */ int p[30]; /** Funkcja sprwadzajaca, czy zadana liczba mozliwa do zbudowania z liczb pierwszych z zadania */ bool checkIfValid(int64_t val) { if(val==1) return true; for(int i=0;i<k;++i) { while(val%p[i]==0) val/=p[i]; if(val==1) return true; } return false; } /** Proste sprawdzanie dla malych ilosci */ void simpleProcess() { int64_t t=N; for(;;) { if(checkIfValid(t)) { cout<<t<<endl; return; } --t; } } class Calc { public: /** Juz wyliczone liczby */ vector<int64_t> mem; int64_t best=0; void genNext() { int64_t v=mem[mem.size()-1]; while(v>1) { --v; if(checkIfValid(v)) { mem.push_back(v); break; } } } void findFirst() { int maxP=0; int minP=97; for(int i=0;i<k;++i) { if(p[i]>maxP) maxP=p[i]; if(p[i]<minP) minP=p[i]; } int64_t limit=(int64_t)pow(N, 1.0/3); int64_t limit2=limit*(int64_t)minP; // int64_t limit2=limit*(int64_t)3; int64_t v=0; // int l3=max(5000/k, 25); int l3=1610; int cnt=0; //cout<<"Limit: "<<limit<<" Limit2: "<<limit2<<endl; for(int64_t i=limit;v==0 || i<limit2;++i) { if(checkIfValid(i)) { ++cnt; v=i; if(cnt==l3) { //cout<<"CNT Break"<<endl; break; } } } mem.push_back(v); //cout<<"Max val: "<<mem[0]<<endl; } void calc() { for(int i1=0;;++i1) { const int64_t v1=mem[i1]; //cout<<"Processing i1["<<i1<<"]="<<v1<<endl; for(int i2=i1;;++i2) { const int64_t v2=mem[i2]; const int64_t part=v1*v2; bool done=false; if(part>N) { if(i2+1>=mem.size()) genNext(); continue; } const int64_t limit=N/part; if(limit==1) { if(part>best) best=part; break; } for(int i3=i2;;++i3) { if(i3>=mem.size()) genNext(); const int64_t v3=mem[i3]; if(v3<=limit) { int64_t res=part*v3; if(res>best) best=res; if(i3==i1) return; if(i3==i2) done=true; break; } } if(done) break; } } } }; int main(int argc, char** argv) { // przyspiszenie cin/cout ios_base::sync_with_stdio(false); cin.tie(NULL); // odczyt danych cin>>k>>N; for(int i=0;i<k;++i) cin>>p[i]; if(N<10000000) { // proste sprawdzanie simpleProcess(); } else { Calc c; c.findFirst(); c.calc(); cout<<c.best<<endl; } return 0; } |